使用参数创建自定义 UIView 初始化方法

Posted

技术标签:

【中文标题】使用参数创建自定义 UIView 初始化方法【英文标题】:Creating custom UIView init method with parameters 【发布时间】: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]??

【问题讨论】:

【参考方案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 方法,无论您喜欢还是适用于您的用例。

【讨论】:

以上是关于使用参数创建自定义 UIView 初始化方法的主要内容,如果未能解决你的问题,请参考以下文章

如何将额外的参数传递给自定义UIView类以便在swift中进行初始化

为UIView自定义Xib

如何将值从 XIB 传递到 UIView 初始化程序?

初始化自定义类 UIVIew

如何使用不同的 init 方法在 XIB 中创建自定义视图?

自定义 UIView 子类添加 nib 子视图