【问题标题】:How do I create reusable iOS controls?如何创建可重用的 iOS 控件?
【发布时间】:2011-06-24 00:30:17
【问题描述】:

作为一名新的 iOS 开发人员,我正在尝试确定在 iOS4+ 中创建可重用控件的最佳方法。例如,如果我想创建一个可以在多个其他视图中使用的自定义 UIImageView,那么最好的方法是什么。

我创建了包含以下文件的控件:

  • MyImageViewController.h
  • MyImageViewController.m
  • MyImageViewController.nib

假设我想要一个使用 .nib 文件的控件。

我将如何执行以下操作:

  1. 以编程方式和通过 IB 在另一个视图中创建自定义控件的实例?
  2. 如何构建自定义控件以便它可以公开“事件”,例如 ontouch?
  3. 如何构建自定义控件以便调用操作/方法,例如 loadImage()?

任何见解或参考表示赞赏。 谢谢

【问题讨论】:

    标签: objective-c ios xcode


    【解决方案1】:

    可能不会使用 nib/xib 来创建可重复使用的视图“控件”。 iOS 与您可能习惯的 Java 或 .NET 非常不同。对于某些类型的视图,您将创建一个 xib 和支持它的控制器/类 - UITableViewCell 就是一个例子。

    我希望我可以逐步指导您如何实现您正在尝试做的事情,但我不能,因为我没有足够的信息来说明您实际尝试做的事情。苹果开发者网站上有几个很棒的指南可以让您熟悉 View/Controller/Touch 事件交互,但该网站现在没有响应(我假设是因为 WWDC 视频的发布)。说到,观看 WWDC 2010 的视频将是另一种了解您想要实现的目标的好方法,尤其是 UIKit 会话。

    您不会像您可能习惯的那样创建“控件”,而是自定义 UIView-descendant 对象和自定义 UIViewController-descendant 对象。在我的项目中,我发现创建可重复使用的 UIView 有任何好处的场景非常非常(除了 UITableViewCells)。 iOS 项目中绝大多数可重用的代码都是 ViewControllers。您将通过使用委托来公开事件 - 您的控制器将定义另一个对象将实现的委托,并从您的控制器接收方法调用以处理委托的任何内容。同样,Apple 指南和 WWDC 视频很好地解释了这一点。

    这是一个可重用控制器的示例及其用法:

    MyEntityViewController.m

    - (id)initWithEntity:(EntityFoo *)theEntity inEditMode:(BOOL)inEditMode {
      self = [super initWithNibNamed:@"EntityFooView" bundle:nil];
      if(self) {
        //retain entity somewhere
        //dont setup view in here!
      }
      return self;
    }
    
    - (void)viewDidLoad {
      //setup view in here. This ensures compatibility with standalone operation
    }
    

    RootViewController.m

    - (void)viewDidLoad {
      [super viewDidLoad];
    
      EntityViewController *evc = [[EntityViewController alloc] initWithEntity:self.someEntity inEditMode:NO];
      [self.view addSubview:evc.view];
    
      //You MUST call this method, the framework will not call it on sub-controllers
      [evc viewDidLoad];
    
      self.entityViewController = evc;
      [evc release];
    }
    

    这不是一个完整的实现,随着您的经验和框架的增长,您会发现在主视图控制器中通知(提示提示)子视图控制器事件的​​模式。我强烈建议您观看 WWDC 2011 视频(如果您可以访问它们),因为下一个操作系统中会出现与此主题相关的内容。

    【讨论】:

    • 我已经阅读了大部分 Apple 开发人员文档,他们解释了视图控制器、视图等,但大多数示例都是简单的一次性创建 UI 元素。我想做的一件事是创建 4 个独立视图,每个视图都有自己的控制器,然后将它们嵌套在容器视图中。四个视图中的两个在应用程序的其他地方使用。所有这些都是相当复杂的布局,并且受益于使用 .nib 文件而不是以编程方式进行。所以一个简单的问题是,如果我有 ViewA,我将如何创建它的实例并将其包含在 ViewB 中?你是实例化控制器还是加载 .nib 文件?
    • 两者都被实例化了。 UIViewController 有一个 -initWithNibNamed:bundle: 方法,我通常在我的可重用控制器中将其重写为类似于 -initWithEntity:editMode:,然后在该初始化中我将调用 [super initWithNibNamed:bundle:] 并传入名称笔尖文件。这样我的控制器的消费者就不需要知道它使用的是什么笔尖,一切正常。在调用代码中,您初始化控制器,然后将其视图添加为容器控制器的子视图。请注意,您必须手动检测控制器方法 - SDK
    【解决方案2】:

    Here's an article 描述了如何使用 nib 创建可重用控件。名为“A reusable subview”的部分听起来像你想要的。

    与@RyanR 所说的相反,在 iOS 中创建一个可重用的控件非常好。这不是我经常看到的模式,但你完全可以做到。

    【讨论】:

    • 你是对的,创建可重用的控件很好。看看 Apple 是如何做到的 - UIScrollView 或任何其他 UIKit 控件都是 UIView 的后代,而不是 UIViewController。我刚刚意识到,任何类似控件的小视觉元素都不需要 UIViewController 的子类 - UIView 子类(可选地带有自己的 xib)会更简单。
    【解决方案3】:

    这是我的故事板版本。

    添加视图控制器ID:

    在 .h 文件中创建一个属性来保存控制器。否则将从内存中删除:

    @property (nonatomic, strong) TestViewController *timetableViewController;
    

    在 .m 文件中:

    -(void)viewDidLoad{
        [super viewDidLoad];
        TestViewController *centerViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"VIEW_CONTROLLER_ID"];
        [self.view addSubview:centerViewController.view];
        [centerViewController viewDidLoad];
        self.timetableViewController = centerViewController;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-23
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 2023-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多