如何以编程方式从NIB复制UIView?

时间:2015-02-14 18:52:55

标签: ios

我需要将多次在IB中创建的UIView添加到scrollView中。有点像TableView Cell。以下代码仅创建一次View。我当然可以以编程方式创建UIView并使其工作,但这会使AutoLayout更加困难。

问题:如何在StoryBoard中创建带子视图的视图(例如ImageView,Labels等)并在scrollView中复制它?

class ScrollViewController: UIViewController {

@IBOutlet var backgroundView: UIView!

let scrollView = UIScrollView()


override func viewDidLoad() {
    super.viewDidLoad()

    let height = CGFloat(200.0)

    self.scrollView.frame = self.view.bounds

    //Make scrollView (height) = number of UIViews
    self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, height*2) 
    self.view.addSubview(self.scrollView)

    var y = CGFloat(0.0)

    for i in 0..<2 {

        backgroundView.frame = CGRectMake(0, y, 20, 20)
        self.scrollView.addSubview(backgroundView)

    y += height
    }

}

see screenshot:

1 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是将视图放在其自己的XIB中。在代码中,创建UINib的单个实例并重复发送instantiateWithOwner:options:。这可能是最简单的解决方案。

如果您坚持使用故事板,则可以将视图置于其自己的视图控制器下。然后,您可以使用-[UIStoryboard instantiateViewControllerWithIdentifier:]加载视图控制器和视图的多个副本。要正确执行此操作,您需要了解view controller containment

另一种方法是使用+[NSKeyedArchiver archivedDataWithRootObject:]将视图序列化为存档。然后,您可以使用+[NSKeyedUnarchiver unarchiveObjectWithData:]重复反序列化归档程序。但是,如果您的视图(或其任何后代视图)具有对其他对象(如模型或控制器对象)的引用,则最终可能会复制比您预期的更大的对象图。

更新

假设您创建了名为UIView的{​​{1}}自定义子类。选择File&gt;创建XIB;新&gt;菜单栏中的文件。在对话框中,选择iOS&gt;用户界面,然后单击“查看”图标。将XIB命名为MyView。将XIB中视图的自定义类设置为MyView.xib。布置MyView的子视图,设置约束,并将MyView的出口连接到其子视图。

要加载XIB,您需要创建MyView的实例,然后重复发送UINib。我会在instantiateWithOwner:options:上的类方法中执行此操作,如下所示:

MyView

请注意,我在这里遇到了一些额外的麻烦,要在低内存警告上丢弃@implementation MyView static UINib *nib; + (instancetype)instantiate { if (nib == 0) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; NSString *myClassName = NSStringFromClass(self); NSBundle *myClassBundle = [NSBundle bundleForClass:self]; nib = [UINib nibWithNibName:myClassName bundle:myClassBundle]; } NSArray *topLevelObjects = [nib instantiateWithOwner:nil options:nil]; return [topLevelObjects firstObject]; } + (void)didReceiveMemoryWarning { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; nib = nil; } @end 对象。

无论如何,要创建UINib的实例,您可以这样做:

MyView

如果需要,将创建MyView *myView = [MyView instantiate]; 对象,然后让它实例化视图。每次调用都将返回从XIB加载的UINib的新实例。