【问题标题】:Creating custom UIView init method with parameters使用参数创建自定义 UIView 初始化方法
【发布时间】:2014-02-24 13:25:24
【问题描述】:

我正在寻找如何使用传入参数的自定义 init 方法正确地继承 UIView

我在这里阅读了UIView 类参考文档:https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html

目前 UIView 正在UIViewController 中创建,并且可以移动/重构到它自己的子类中。此外,目前视图完全是在代码中创建的,并且框架是通过添加到视图本身的约束来计算的。

文档说如下

initWithFrame: - 建议你实现这个方法。除了或代替此方法,您还可以实现自定义初始化方法。

问题
因为我没有创建一个框架作为视图的起点/它也不是从 XIB 加载的,所以对它进行子类化的正确过程是什么?

这是否正确:

-(id)init {
    NSLog(@"%s",__PRETTY_FUNCTION__);
    self = [super init];
    if (self) {
        // Init code
        [self spmCustomInit];
    }
    return self;
}

-(void)spmCustomInit {
    NSLog(@"%s",__PRETTY_FUNCTION__);

}

如果这是正确的,我需要进一步更改。创建视图时,它会根据信息创建一些子视图。此外,布局也因难度级别而异。 其他问题
如何创建传入参数的进一步自定义 init 方法?
例如,如果我创建了一个名为

的方法
spmInitWithWord:(NSString *)word difficulty:(GameTurnDifficulty)difficulty

然后如何调用标准的 init 方法。然后我会在最初创建视图时调用这个自定义初始化吗? [[UICustomViewExample alloc] spmInitWithWord:testWord difficulty:turnDifficulty]??

【问题讨论】:

    标签: ios objective-c uiview ios6 ios7


    【解决方案1】:

    不,我会建议一种不同的方法。编写你的 init 方法来调用 super initWithFrame。这是 UIView 的指定初始化程序。通过自己调用它,您可以确保调用任何需要进行的操作系统设置。

    如果需要,您可以将 CGRectZero 作为框架传入,然后再设置框架。

    请注意,您还应该计划支持使用 initWithCoder 进行初始化。如果您将视图放入 XIB 文件或 Storyboard 中,就会调用该方法。

    我所做的是创建一个方法 doInitSetup,并将我的自定义初始化放在那里。然后我从 initWithFrame 和 initWithCoder 调用该方法。

    在您的情况下,您可以为自定义设置添加属性,如果您将其中一个视图放在 XIB/Storyboard 中,则可以使用用户运行时属性设置这些属性。

    使用 IB 来设计表单是个好主意。我会建议你学习使用它们。它们使类似变得更容易,并让您可以访问几乎不可能通过代码使用的功能。

    您的代码可能如下所示:

    - (id) initWithWord: (NSString *) theWord
    {
       self = [super initWithFrame: CGRectZero];
       if (!self)
         return nil;
       [self doInitSetupWithWord: theWord];
       return self;
    }
    
    - (void) doInitSetupWithWord: (NSString *) theWord
    {
      //Do whatever you need to do to set up your view.
    }
    
    
    - (id) initWithCoder:(NSCoder *)aDecoder
    {
      self = [super initWithCoder: aDecoder];
      if (!self) {
        return nil;
      }
    
      [self doInitSetupWithWord: nil];
      return self;
    }
    
    - (void) setWord: (NSString *) theWord
    {
      _theWord = theWord;
      //If possible, set things up for the new word
    }
    

    【讨论】:

    • 感谢@Duncan C - 实际上在这种情况下,对于 IB 来说,这种观点太先进了,至少我认为会这样。我根据传递来创建此自定义视图的单词动态创建子视图(如磁贴),因此视图通常非常不同。在您的回答中,您说创建自定义doInitSetup,然后从initWithFrame 等调用该方法。我的问题是我需要一个完全自定义的初始化(最后一个问题),例如initWithWord。如果我实施这种方法,我应该像下面的其他答案建议的那样调用标准的 self init 。如果有助于解释,请使用代码示例?
    【解决方案2】:

    假设您的自定义方法如下

    -(instancetype) initWithFrame:(CGRect)frame base:(UIColor *)base textColor:(UIColor *)textColor
    {
        if(self = [super initWithFrame:frame])
        {
            self.backgroundColor = base;
            self.label.textColor = textColor;
        }
        return self;
    }
    

    if 条件创建您的 UIView 对象,您可以根据您的参数进一步自定义该对象。您可以使用 initWithFrame: 或 init 方法,无论您喜欢还是适用于您的用例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2017-04-26
      • 2019-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多