草庐IT

ios - UIButton 执行选择器 :withObject:withObject: not making call

coder 2024-01-18 原文

这是我的代码。

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(110, 270, 100, 40);
    button.backgroundColor = [UIColor grayColor];
    [button setTitle:@"next" forState:UIControlStateNormal];
    [self.view addSubview:button];

我想通过这个方法设置按钮标题颜色 但它不起作用!

    [button performSelector:@selector(setTitleColor:forState:)
                 withObject:[UIColor blackColor]
                 withObject:@(UIControlStateNormal)];

有人知道为什么它不起作用吗???


感谢大家的帮助。 昨晚,我找到了一种让它起作用的方法。无论参数是 UIControlStateNormal(特例)还是其他类似 UIControlStateHighlighted 的。 这是代码:

     [button performSelector:@selector(setTitleColor:forState:)
                  withObject:[UIColor blueColor]
                  withObject:(__bridge id)((void *)UIControlStateNormal)];
     [button performSelector:@selector(setTitleColor:forState:)
                  withObject:[UIColor blackColor]
                  withObject:(__bridge id)((void *)UIControlStateHighlighted)];
     [button performSelector:@selector(setTitleColor:forState:)
                  withObject:[UIColor redColor]
                  withObject:(__bridge id)((void *)UIControlStateSelected)];

那么问题就解决了。


我发现它很有用!所以我想用它做更多的事情, 这是代码:

    [button.layer performSelector:@selector(setMasksToBounds:) withObject:(__bridge id)((void *)YES)];
    [button.layer performSelector:@selector(setCornerRadius:) withObject:(__bridge id)((void *)5)];
    [button.layer performSelector:@selector(setBorderWidth:) withObject:(__bridge id)((void *)5)];
    [button.layer performSelector:@selector(setBorderColor:) withObject:(__bridge id)(__bridge CGColorRef)[UIColor greenColor]];

我测试的时候发现又不行了!!!太失望了:(。如果有人对这个问题感兴趣,你可以测试一下。

最佳答案

如果我理解你的意图是正确的,你要求让框架进行相应的调用,所以你期望

[button performSelector:@selector(setTitleColor:forState:)
                 withObject:[UIColor blackColor]
                 withObject:@(UIControlStateNormal)];

打电话

[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

您在这里遗漏了一件重要的事情:performSelector:withObject:withObject: 需要两个对象。您将纯整数值(因为 UIControlStateNormal 是一些 int/enum 值)包装在 NSNumber 中。现在该对象(或指针、地址,或任何您调用它的东西)作为第二个参数传递给 setTitleColor:forState:,这显然不是值本身,但因为该方法不知道this,它将值解释为某种整数值。

所以稍后会调用这样的东西:

NSNumber *number = ...; // your number object
[button setTitleColor:[UIColor blackColor] forState:number];

正如在另一个答案中所说,它可能通过省略此处的 @(...) 运算符来工作,因此该值不会包含在 NSNumber 中。这就是将要发生的事情:NSControlStateNormal 被定义为 0。所以编译器会将其解释为 nil,这是一个有效的对象,或者缺少对象。 nil 稍后将被重新解释为整数值作为 UIControlState,因此您的 0 (== UIControlStateNormal) 再次。

这是一个可行的特殊情况,因为 0 可能被视为 nil。它不会与任何其他值(即 UIControlStateFocused)一起工作(通常甚至不会编译)。你会得到一个 “无法使用类型为‘(匿名枚举...)’的右值初始化类型为‘id’的参数”错误。

如果你坚持走 performSelector: 路线,你可以添加这样的方法:

-(void)setProperties:(NSDictionary *)props onButton:(UIButton *)button {
   UIColor *color = props[@"color"];
   NSNumber *stateWrapper = props[@"state"];
   UIControlState state = (UIControlState)stateWrapper.unsignedIntegerValue;
   [button setTitleColor:color forState:state];
}

并像这样使用它:

[self performSelector:@selector(setProperties:onButton:) 
           withObject:@{@"color" : [UIColor blackColor], 
                        @"state" : [NSNumber numberWithUnsignedInteger:UIControlStateNormal]} 
           withObject:button];

将值包装到 NSValue 中甚至可能更清晰,或者为您的参数使用专用类等。

但是,无论如何,我更喜欢 dispatch_* 方法,即

dispatch_sync(dispatch_get_main_queue(), ^{
    [button setTitleColor:[UIColor blackColor] forState:number];
})

或使用 dispatch_async 或您当时的意图。

关于ios - UIButton 执行选择器 :withObject:withObject: not making call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37962462/

有关ios - UIButton 执行选择器 :withObject:withObject: not making call的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. ruby - Rails 3 的 RGB 颜色选择器 - 2

    状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基

  7. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  10. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

随机推荐