【问题标题】:Initialization of a custom UIView in a UIViewController using a storyboard使用情节提要在 UIViewController 中初始化自定义 UIView
【发布时间】:2014-04-12 13:17:34
【问题描述】:

我有一个自定义 UIViewcontroller,想要初始化并分配一个自定义 UIView,我之前分配给 IBOutlet。我正在使用故事板。谁能给我提示在哪里调用自定义 UIView 的指定初始化程序?

**MyCustomUIView.h**

@interface MyCustomUIView : UIView

@end

**MyCustomUIView.m**
@implementation MyCustomUIView 
- (id)initWithNumberOfHeaderRows:(NSUInteger)headerRowCount numberOfHeaderColumns:(NSUInteger)headerColumnCount frame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {

    }
    return self;
}
@end


**MyUIViewController.h**
@interface MyUIViewController : UIViewController
@property (weak, nonatomic) IBOutlet MyCustomUIView *myCustomUIView; // I wanna use this Outlet
@end

**MyUIViewController.m**
@implementation MyUIViewController 

@end

这是所用 github 源代码的抽象版本:https://github.com/mutualmobile/MMSpreadsheetView/blob/master/MMSpreadsheetView/MMSpreadsheetView.m

【问题讨论】:

    标签: ios objective-c uistoryboard designated-initializer


    【解决方案1】:

    可以在控制器的viewDidLoad中调用自定义视图的构造函数(初始化器)。然后,将其添加为控制器视图的子视图。

    类似这样的:

    - (void)viewDidLoad {
        ...
        MyCustomUIView *customView = [MyCustomUIView alloc] initWithNumberOfHeaderRows:0 numberOfHeaderColumns:0 frame:CGRectZero];
        [self.view addSubview:customView];
        ...    
    }
    

    更新

    我认为您应该像这样创建自定义视图类:

    //MyCustomView.h
    @interface MyCustomView : UIView
    
    - (id)initWithNumberOfHeaderRows:(NSUInteger)numberOfHeaderRows numberOfHeaderColumns:(NSUInteger)numberOfHeaderColumns;
    
    @property (readwrite, nonatomic) NSUInteger numberOfHeaderRows;
    @property (readwrite, nonatomic) NSUInteger numberOfHeaderColumns;
    
    @end
    
    //MyCustomView.m
    @implementation
    
    - (void)setup {
        // Do custom stuffs here...
    }
    
    - (id)initWithNumberOfHeaderRows:(NSUInteger)numberOfHeaderRows numberOfHeaderColumns:(NSUInteger)numberOfHeaderColumns {
        self = [self initWithFrame:CGRectZero];
        if (self) {
            self.numberOfHeaderRows = numberOfHeaderRows;
            self.numberOfHeaderColumns = numberOfHeaderColumns;
        }
        return self;
    }
    
    - (id)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    - (id)init {
        self = [super init];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    - (id)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if (self) {
            [self setup];
        }
        return self;
    }
    
    @end
    

    然后在viewDidLoad中:

    - (void)viewDidLoad {
        ...
        // Assuming you have an IBOutlet property of MyCustomView class with a name 'customView'
        // That property must be hooked up from the xib/storyboard
        self.customView.numberOfHeaderRows = 1;
        self.customView.numberOfHeaderColumns = 1;
        self.customView.frame = self.view.bounds;
        ...
    }
    

    更新 2

    您可以简单地添加一个公共方法来设置自定义视图中的标题行和列数。

    //MyCustomView.h
    @interface MyCustomView : UIView
    
    ...
    - (void)setNumberOfHeaderRows:(NSUInteger)rows numberOfHeaderColumns:(NSUInteger)columns; 
    ...
    
    @end
    
    //MyCustomView.m
    @implementation MyCustomView
    
    ...
    - (void)setNumberOfHeaderRows:(NSUInteger)rows numberOfHeaderColumns:(NSUInteger)columns {
        //Do the custom stuffs that you want...
    }
    ...
    
    @end
    

    然后在viewDidLoad中

    - (void)viewDidLoad {
        ...
        [self.customView setNumberOfHeaderRows:10 numberOfHeaderColumns:4];
        ...
    }
    

    更新 3

    根据您提供的参考文件,您可以在 DataSource 中添加方法:

        //MMSpreadsheetView.h
        @optional
        ...
        - (NSUInteger)spreadsheetViewNumberOfHeaderRows:(MMSpreadsheetView *)spreadsheetView;
        - (NSUInteger)spreadsheetViewNumberOfHeaderColumns:(MMSpreadsheetView *)spreadsheetView;
        ...
    

    那么,在实现文件中:

    //MMSpreadsheetView.m
    ...
    - (void)setupWithNumberOfHeaderRows:(NSUInteger)rows numberOfHeaderColumns:(NSUInteger)columns {
        _scrollIndicatorInsets = UIEdgeInsetsZero;
        _showsVerticalScrollIndicator = YES;
        _showsHorizontalScrollIndicator = YES;
        _headerRowCount = headerRowCount;
        _headerColumnCount = headerColumnCount;
    
        if (headerColumnCount == 0 && headerRowCount == 0) {
            _spreadsheetHeaderConfiguration = MMSpreadsheetHeaderConfigurationNone;
        }
        else if (headerColumnCount > 0 && headerRowCount == 0) {
            _spreadsheetHeaderConfiguration = MMSpreadsheetHeaderConfigurationColumnOnly;
        }
        else if (headerColumnCount == 0 && headerRowCount > 0) {
            _spreadsheetHeaderConfiguration = MMSpreadsheetHeaderConfigurationRowOnly;
        }
        else if (headerColumnCount > 0 && headerRowCount > 0) {
            _spreadsheetHeaderConfiguration = MMSpreadsheetHeaderConfigurationBoth;
        }
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        self.backgroundColor = [UIColor grayColor];
        [self setupSubviews];
    }
    
    - (id)initWithNumberOfHeaderRows:(NSUInteger)headerRowCount numberOfHeaderColumns:(NSUInteger)headerColumnCount frame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            [self setupWithNumberOfHeaderRows:rows numberOfHeaderColumns:columns];
        }
        return self;
    }
    
    - (id)initWithCoder:(NSCoder *)aDecoder {
        self = [super initWithCoder:aDecoder];
        if (self) {
            NSUInteger rows = 0;
            NSUInteger columns = 0;
            if (self.dataSource && [self.dataSource respondsToSelector:@selector(spreadsheetViewNumberOfHeaderRows:)]) {
                rows = [self.dataSource spreadsheetViewNumberOfHeaderRows:self];
            }
            if (self.dataSource && [self.dataSource respondsToSelector:@selector(spreadsheetViewNumberOfHeaderColumns:)]) {
                columns = [self.dataSource spreadsheetViewNumberOfHeaderColumns:self];
            }
            [self setupWithNumberOfHeaderRows:rows numberOfHeaderColumns:columns];
        }
        return self;
    }
    ...
    

    【讨论】:

    • 对。我以前这样做过,它奏效了。只是想知道反过来。在通过界面生成器为我的 MyUIView 类型的 UIView 分配自定义类之后。我想使用 MyUIViewController 中的 IBOutlet 使用 MyUIView 的指定初始化程序对其进行初始化。根据你的说法,我会有一个 MyUIView,它有一个子视图,它又是一个 MyCustomView……你找到我了吗?
    • 我想要这个 myCustomUIView = [MyCustomView alloc] initWithNumberOfHeaderRows: 1 numberOfHeaderColumns:1 frame:anyFrame.bounds.]; myCustomUIView 是 MyUIView 类型的 IBOutlet。
    • 非常感谢您对我的帮助。如果我声明了实例变量,我会需要更多,因为这个初始化器不仅仅做简单的事情。然后我需要更多的设置:(。因此我想要一个与 initWithCoder 结合的解决方案......但我有点没有。
    • 我没有注意到第三个。我会试试看。再次非常感谢您。
    • 好吧,这个解决方案的问题是在 initWithCoder 中数据源为 nil,因此不会调用数据源方法。
    【解决方案2】:

    另一种选择是为您的视图采用数据源模式。例如,在 MyCustomUIView.h 中:

    @class MyCustomUIView;
    
    @protocol MyCustomUIViewDataSource
    - (NSInteger)numberOfHeadersInMyCustomUIView:(MyCustomUIView *)view;
    - (NSInteger)numberOfHeaderColumnsInMyCustomUIView:(MyCustomUIView *)view;
    @end
    
    @interface MyCustomUIView : UIView
    
    @property (nonatomic, strong) id<MyCustomUIViewDataSource> dataSource;
    
    @end
    

    在 MyCustomUIView.m 中添加:

    - (void)setDataSource:(id<MyCustomUIViewDataSource>)dataSource {
        self.dataSource = dataSource;
        self.headerRowCount = [self.dataSource numberOfHeadersInMyCustomUIView:self];
        self.headerColumnsCount = [self.dataSource numberOfHeaderColumnsInMyCustomUIView:self];
    
        // Rearrange view with the new values
    }
    

    然后在你的 UIViewController 中:

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.myCustomUIView.dataSource = self;
    }
    
    - (NSInteger)numberOfHeadersInMyCustomUIView:(MyCustomUIView *)view {
        return 5;
    }
    
    - (NSInteger)numberOfHeaderColumnsInMyCustomUIView:(MyCustomUIView *)view {
        return 2;
    }
    

    您甚至可以在自定义视图中添加重新加载方法。

    【讨论】:

    • 是的,也非常感谢。我也会接受这个作为解决方案。
    猜你喜欢
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 2012-08-09
    • 2013-07-18
    • 1970-01-01
    • 2015-12-04
    相关资源
    最近更新 更多