jjzjj

iOS - 更改 UIButton 或自定义 UIButton 的渐变背景

coder 2024-01-16 原文

我使用 .h 文件创建了自己的派生自 UIButton 的类:

@interface MenuButton : UIButton

- (void)changeBackground;

@end

在实现中,我尝试添加一些改变背景的方法,但到目前为止没有成功:

#import "MenuButton.h"
#import "GradientLayers.h"

@implementation MenuButton

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder;
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonInit];
    }
    return self;
}

- (void)commonInit;
{

    // Gradient background
    CAGradientLayer *gradient = [GradientLayers darkBlueBackground];
    gradient.frame = [self layer].bounds;

    // Insert background
    [[self layer] insertSublayer:gradient atIndex:0];

    [[self layer] setCornerRadius:10.0f];
    [[self layer] setMasksToBounds:YES];
    [[self layer] setBorderWidth:2];
    [[self layer] setBorderColor:[[UIColor blackColor] CGColor]];

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    // handle touch
    [super touchesEnded:touches withEvent:event];

    if ([self state] != UIControlStateSelected)
    {
        CAGradientLayer *gradient = [GradientLayers blackBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
    else
    {
        CAGradientLayer *gradient = [GradientLayers darkBlueBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
}

- (void)changeBackground
{
    CAGradientLayer *gradient = [[[self layer] sublayers] firstObject];
    gradient = [GradientLayers blackBackground];
    [[self layer] insertSublayer:gradient atIndex:0];
    [self setNeedsDisplay];
}

@end

部分GradientLayer.m文件:

#import "GradientLayers.h"

@implementation GradientLayers

+ (CAGradientLayer*) blackBackground {
    // similar to darkBlueBackground
}

+ (CAGradientLayer*) darkBlueBackground {
    // Create colors
    UIColor *darkOp = [UIColor colorWithRed:0.039f green:0.106f blue:0.278f alpha:1.0];
    UIColor *lightOp = [UIColor colorWithRed:0.133f green:0.267f blue:0.65f alpha:1.0];

    // Create gradient
    CAGradientLayer *gradient = [CAGradientLayer layer];

    // Set colors
    gradient.colors = [NSArray arrayWithObjects:
                       (id)lightOp.CGColor,
                       (id)darkOp.CGColor,
                       nil];

    // Shadow
    gradient.shadowOffset = CGSizeMake(3.0f, 3.0f);
    gradient.shadowColor = [UIColor blackColor].CGColor;
    gradient.shadowOpacity = 0.6;
    gradient.shadowRadius = 10;

    // Other options
    gradient.borderWidth = 0.5f;
    gradient.borderColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0].CGColor;
    gradient.cornerRadius = 10;

    return gradient;
}

@end

我的按钮在 commonInit 中设置了 darkBlueBackground。这不是问题。但我想在用户点击按钮后更改它,但到目前为止还没有运气。如果我设置断点我在 touchesEnded 或 changeBackground 但执行后按钮具有与以前相同的背景。那么如何将背景更改为另一个渐变背景呢?谢谢

最佳答案

因为 [self layer].sublayers 数组以从后到前的顺序列出 ( https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instp/CALayer/sublayers ),通过在索引 0 处插入替换层,您我们总是把它放在旧渐变的后面。

您应该删除旧的渐变层,然后添加新的。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    // handle touch
    [super touchesEnded:touches withEvent:event];

    // Remove old gradient here
    [[[[self layer] sublayers] objectAtIndex:0] removeFromSuperlayer];

    if ([self state] != UIControlStateSelected)
    {
        CAGradientLayer *gradient = [GradientLayers blackBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
    else
    {
        CAGradientLayer *gradient = [GradientLayers darkBlueBackground];
        gradient.frame = [self layer].bounds;
        [[self layer] insertSublayer:gradient atIndex:0];
    }
}

- (void)changeBackground
{
    // Remove old gradient here
    [[[[self layer] sublayers] objectAtIndex:0] removeFromSuperlayer];

    CAGradientLayer *gradient = [[[self layer] sublayers] firstObject];
    gradient = [GradientLayers blackBackground];
    [[self layer] insertSublayer:gradient atIndex:0];
    [self setNeedsDisplay];
}

您真的应该更好地跟踪渐变,这样您就不会经常删除它并用相同的渐变替换它。也许只是显示和隐藏所选状态,它总是位于未突出显示的版本之上。

关于iOS - 更改 UIButton 或自定义 UIButton 的渐变背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22908369/

有关iOS - 更改 UIButton 或自定义 UIButton 的渐变背景的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  3. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  4. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  5. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  6. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  7. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  8. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  9. ruby-on-rails - 使用 Rmagick 或 ImageMagick 在背景上放置标题 - 2

    我有一张背景图片,我想在其中添加一个文本框。我想弄清楚如何将标题放置在其顶部的正确位置。(我使用标题是因为我需要自动换行功能)。现在,我只能让文本显示在左上角,但我需要能够手动定位它的开始位置。require'RMagick'require'Pry'includeMagicktext="Loremipsumdolorsitamet"img=ImageList.new('template001.jpg')img 最佳答案 这是使用convert的ImageMagick命令行的答案。如果你想在Rmagick中使用这个方法,你必须自己移植

  10. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

随机推荐