0

I am designing a Custom UIView for my app.

The UIView will comprise of below components:

  1. UISearchbar
  2. UITableView

My initialiser is below:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        _searchBar = [[UISearchBar alloc]initWithFrame:CGRectZero];
        _tableView = [[UITableView alloc]initWithFrame:CGRectZero];
        _tableView.dataSource = self;
        [super addSubView:_searchBar];
        [super addSubView:_tableView];
        // Initialization code
    }
    return self;
}

I am planning to set the frame of the _searchBar and _tableView in layoutsubviews method.

But I think think the way I have added the _tableView to super is wrong. Because the moment the _tableView is added to subview the data source methods of the _tableView will be triggered. And this happens even before the creation of the custom class itself.

Is this a correct design?

Can I add just _tableView alone in layoutSubviews as in below manner?

-(void)layoutSubViews{

//Adjust frame 
[_tableView removeFromSuperView];
[self addSubView:_tableView];

}
RK-
  • 12,099
  • 23
  • 89
  • 155

2 Answers2

1

You should definitely add it in init, because layout sub-views will get called each time you view will resize and will need to re-layout its sub-views. Layout subviews method is strictly use as a callback telling you that your view will layout, and is used as an override point for any additional layout you wish to make. Also, as an additional note, it's not good design adding the view using super.

Vlad
  • 3,346
  • 2
  • 27
  • 39
  • Why is that we should not add on super? Can we add it as below?[self addSubView:tableView]; But here since the data source is set in initializer the data source methods will be triggered right? – RK- Feb 08 '13 at 10:18
  • 1
    Use the add subview in your super class implementation on self, why add from here on super ? It just complicates things more. And yes, data source callbacks will still be called, however, it's recommended to set your data source and delegate handling inside a controller rather than a view. A view stricly does layout / drawing / things related to UI layer, while a controller handles content/ logic / things related to business layer, etc. Your approach does not comply with the MVC pattern. – Vlad Feb 08 '13 at 10:57
  • +1 Thanks Vlad for the clarification..I upvoted your answer and comment..I found the answer of rocky as most apt for me..and I am accepting it.. – RK- Feb 11 '13 at 06:35
1

You shouldn't be assigning the UITableViewDataSource in the view. It should be assigned in the ViewController.

You're right. There is no restriction on it. But your question is about design. Imagine something like this:

@implementation CustomViewController

- (void)loadView {
    customView = [[CustomView alloc] initWithFrame:CGRectZero];

    customView.tableView.dataSource = self;
    customView.tableView.delegate = self;
}

With a ViewController, you can control when you initialize your custom view and control when its tableView loads the data. While you can certainly put all of this code into your customView, you will be running into problems much worse than the one you are asking about now.

rocky
  • 3,521
  • 1
  • 23
  • 31
  • There is no such restriction – RK- Feb 08 '13 at 13:23
  • 2
    You can definitely do it, but you shouldn't. Views are not supposed to handle logic nor data. They are supposed to present what's given to them. – Marcio Feb 08 '13 at 15:21
  • I have a doubt here...When we open the internals of a class like this, there is a possibility for the developer who uses this to play with frames of views or controls composed in this class right? Is it good to prohibit user from doing it? – RK- Feb 13 '13 at 07:11
  • Yes. Anyone can modify the view frame or controls in the view. It's not necessary to prohibit access to this. First, because you can't prohibit access to a view's frame and second, you *want* a viewController to access the views controls. If a viewController doesn't have access to a a view's controls, it defeats the purpose of a viewController. – rocky Feb 13 '13 at 18:04
  • You should definitely read "The Model-View-Controller Design Pattern" section here: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6 – rocky Feb 13 '13 at 18:08