如何为具有多个参数的方法创建CKComponentViewAttribute

时间:2015-07-16 14:23:17

标签: ios componentkit

我想为UIButton子类创建一个组件。要设置按钮,我想设置图像。我的问题是我不知道如何制作一个CKComponentViewAttribute,它接受UIButton方法setImage:forState:所需的两个参数。

我试过了:

[CKComponent newWithView:{
  [KGHitTestingButton class],
  {
    {CKComponentActionAttribute(@selector(onMenuTap))},
    {@selector(setImage:forState:), [UIImage imageNamed:@"location_action"]}, @(UIControlStateNormal)},
             }
  } size:{.width = 30, .height = 30}]

但那不会编译。与此版本相同:

    {@selector(setImage:forState:), @[[UIImage imageNamed:@"location_action"]}, @(UIControlStateNormal)]},
             }

我在这里阅读http://componentkit.org/docs/advanced-views.html我需要将输入信息包装到一个对象中。在这种情况下我该怎么做?

更新: 我在这里找到了以下提示https://github.com/facebook/componentkit/issues/265

" CKComponentViewAttribute可以使用任意块进行初始化。这是一个例子:

static const CKComponentViewAttribute titleShadowColorAttribute = {"MyComponent.titleShadowColor", ^(UIButton *button, id value){
  [button setTitleShadowColor:value forState:UIControlStateNormal];
}};

"

这就是我最终设法解决问题的方法:

static const CKComponentViewAttribute imageAttribute = {"LocationActionButton.imageAttribute", ^(UIButton *button, id value){
    [button setImage:value forState:UIControlStateNormal];
}};
CKComponent *locationActionButton = [CKComponent newWithView:{
    [UIButton class],
    {
        {@selector(setBackgroundColor:), [UIColor redColor]},
        {imageAttribute, [UIImage imageNamed:@"location_action"]}
    }
} size:{.width = 30, .height = 30}];

你可以内联它来缩短它:

CKComponent *locationActionButton = [CKComponent newWithView:{
    [UIButton class],
    {
        {@selector(setBackgroundColor:), [UIColor redColor]},
        {{"LocationActionButton.imageAttribute", ^(UIButton *button, id value){
            [button setImage:value forState:UIControlStateNormal];
        }}, [UIImage imageNamed:@"location_action"]}
    }
} size:{.width = 30, .height = 30}];

2 个答案:

答案 0 :(得分:0)

您可以解决此问题的一种方法是为使用参数传递集合的类创建一个私有类别,然后按预期应用。如下所示:

@interface KGHitTestingButton (CKPrivate)
- (void)_ckSetImageforState:(NSArray*)args;
@end
@implementation
- (void)_ckSetImageforState:(NSArray*)args {
    [self setImage:args[0] forState:[args[1] integerValue]];
}
@end

...

[CKComponent newWithView:{
      [KGHitTestingButton class],   
      {
          {@selector(_ckSetImageforState:), @[[UIImage imageNamed:@"location_action"]}, @(UIControlStateNormal)]},
         }
 ...

它不漂亮,但它可以解决这个限制。 NSDictionary可以替代,但需要定义一些静态密钥。

答案 1 :(得分:0)

CKComponentViewAttribute有2个初始值设定项。一个是选择器,这是我们使用的最常用的方法。

CKComponentViewAttribute(SEL setter);
// e.g. ' { @selector(setBackgroundColor:), color} '

另一个是

CKComponentViewAttribute(const std::string &ident,
                       void (^app)(id view, id value),
                       void (^unapp)(id view, id value) = nil,
                       void (^upd)(id view, id oldValue, id newValue) = nil) ;

它需要一个标识符和3个块来配置不同条件下的视图。例如,参考更多表单CKComponentViewAttribute.h"CKComponentGestureActions.h"

与你的情况一样:

{ {"setImage",
   ^(UIButton *button, id value) {
     [button setImage:theImageObject forState:UIControlStateNormal]
  },
 @0 // Bogus value, we don't use it.
}