【问题标题】:How to replace pickerView:numberOfRowsInComponent method for 1 instance of pickerView如何替换pickerView:numberOfRowsInComponent 1个pickerView实例的方法
【发布时间】:2015-03-01 08:30:25
【问题描述】:

我想以编程方式创建一个pickerView,并让它使用它自己的方法版本,比如pickerView:numberOfRowsInComponent。

我在运行时这样创建实例:

UIPickerView *myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
myPickerView.delegate = self;
myPickerView.dataSource = self;
myPickerView.showsSelectionIndicator = YES;
[self.view addSubview:myPickerView];

调用的标准方法是:

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    NSUInteger numRows = 5;
    return numRows;
}    

我想做的只是用另一种方法替换这个标准方法。

-(NSInteger)xxxpickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{ // special method for this instance only
    return 1;
}

我已经能够使用方法 swizzle 来处理其他事情,但我似乎无法让它与 UIPickerView 一起使用。

@implementation UIPickerView (Tracking)
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector =   @selector(pickerView:numberOfRowsInComponent:);
        SEL swizzledSelector = @selector(xxxpickerView:numberOfRowsInComponent:);

      Method originalMethod = class_getInstanceMethod(class, originalSelector);
      Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
      BOOL didAddMethod =
      class_addMethod(class,
                    originalSelector,
                    method_getImplementation(swizzledMethod),
                    method_getTypeEncoding(swizzledMethod));

      if (didAddMethod) {
          class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
      } else {
          method_exchangeImplementations(originalMethod, swizzledMethod);
      }

  });

}

我已经列出了方法来查看第二个方法是否在运行时添加到实例中并且它在列表中。

但是,第二个方法不运行,第一个方法运行。

这是一个让我开始着手的帖子的链接,我已经确认它有效,但我似乎遗漏了一些关于此的内容。 http://nshipster.com/method-swizzling/

我愿意接受其他建议,我要解决的问题是我想创建一个 UIPickerView 对象的实例,该对象不依赖于同时运行的另一个实例。因此,我想要一种仅适用于一个实例并完全忽略可能正在运行的任何其他实例的不同方法,并且我想以编程方式执行此操作。

不使用标签/开关的至少一个原因是直到运行时我才知道条件是什么。

我不知道为什么 swizzle 会与一个对象而不是另一个对象一起工作,而且我对在运行时用其他方法替换库存方法的其他方式持开放态度。

我尝试替换的方法是否存在不允许替换的问题?

编辑:为了尝试使问题清楚,链接中的以下代码有效。它将一种方法换成另一种方法。我需要对另一个对象做同样的事情,我无法弄清楚它对一个对象而不是另一个对象起作用。

这适用于另一个对象:http://nshipster.com/method-swizzling/

这里还有另一个链接:http://blog.newrelic.com/2014/04/16/right-way-to-swizzle/

【问题讨论】:

    标签: objective-c uipickerview method-swizzling


    【解决方案1】:

    一种简单的方法是在属性中保留指针的副本,然后比较数据源/委托方法中的指针。

    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        if ( pickerView == self.myPickerView )
            return 1;   // response for this particular picker view
        else
            return 5;   // standard response
    }
    

    【讨论】:

    • 或者也许使用标签或其他一些独特的方式来识别选择器,因为在这种情况下混合似乎太麻烦了......
    • 我以前用过这个,你是对的,它可以在大多数情况下完成这项工作,但我需要让 pickerView 运行不同于标准的方法。 swizzle 方法会将一种方法交换为另一种方法,如上面的链接所示,我只需要找出为什么这适用于一个对象而不适用于另一个对象。它适用于 UIView,但不适用于 UIPickerView。我想知道我是否必须继承 UIPickerView 1st。
    • 也许我在这里走错路了。这就是我想要做的:创建一个类的多个实例(即 UIPickerView),这样该类的每个实例都有它自己的方法。因为它现在有效,他们共享方法,我希望他们有自己独特的方法。它们将在运行时创建,每个方法使用的代码将在运行时确定。
    • UIPickerView 类有一个名为numberOfRowsInComponent 的实例方法。 UIPickerViewDataSource 协议有一个名为pickerView:numberOfRowsInComponent 的方法。你把这两个弄糊涂了。
    猜你喜欢
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2019-09-19
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多