【问题标题】:How to create a CKComponentViewAttribute for a method with multiple arguments如何为具有多个参数的方法创建 CKComponentViewAttribute
【发布时间】:2015-10-06 01:29:56
【问题描述】:

我想为 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}];

【问题讨论】:

    标签: ios componentkit


    【解决方案1】:

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

    @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 是一个替代方案,但需要定义一些静态键。

    【讨论】:

    • 感谢您提出的解决方案。如果您愿意,您的方式可能有点脏,但这是一种非常实用的方式,具有我自己无法想出的通用方法。我用我的解决方案更新了问题。
    【解决方案2】:

    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.
    }
    

    【讨论】:

      猜你喜欢
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      相关资源
      最近更新 更多