1

I have just inherited a code base and the project seems to be made up mainly of UIViews.

Here is an example of a header file for a UIView which was written on 29/07/2014, so the code is relatively new:

#import <UIKit/UIKit.h>

@interface SettingsView : UIView {
    UIView *aView;
    UIViewController *controller;
}
@property(nonatomic,strong)UIView * aView;
@property(nonatomic,strong)UIViewController * controller;

@end

You can see that there is a pointer to a UIViewController. In the implementation file, the mainView is used in a few places. Here is an example:

MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(0, yPos, scroller.frame.size.width, 50)];
myView = 102;
myView = mainView; // Here we are setting another view with this controller.
[scroller myView];

To me this code doesn't feel right. However I would like to know if there is a good reason someone would have a pointer from a UIView to a UIViewController. I have seen my fair share of iOS code over the years and this is the first time I have seen this.

Any insights would be much appreciated.

pls
  • 1,522
  • 2
  • 21
  • 41
  • I agree that this code has a bad smell - it certainly doesn't observe MVC. I suspect the views also have a lot of business logic in them which would be better off in a view controller. – johnpatrickmorgan Aug 22 '15 at 12:10
  • Yeah the views contain almost everything. There are not many UIViewControllers to be seen. The views even handle for example UITableViewDataSource and UITableViewDelegate methods. – pls Aug 22 '15 at 12:25
  • These days just do everything with container views .. http://stackoverflow.com/a/23403979/294884 – Fattie Aug 22 '15 at 14:02

2 Answers2

2

I also use my views like this. I use a variable called "sender" with which UIView keeps track of the UIVC that called it. Then I could do all sorts of logical operations, know the size of the parent, add the view as a subview without explicitly stating it.

Is it the best way? No, it breaks MVC, it doesn't clearly separate UI with functions but it is also a lot more convenient and easier to code with.

You can decide to add buttons or actions in your UIView which will affect its senderVC.

func openWebViewController(#URL: NSURL) {
    var webViewController = SVModalWebViewController(URL: URL)
    senderVC.presentViewController(webViewController, animated: true, completion: nil)
}

Here is a small example of my style of use of pointers to UIVC, sorry its swift but it should be understandable.

https://github.com/goktugyil/CozyLoadingActivity

Esqarrouth
  • 38,543
  • 21
  • 161
  • 168
  • Each to his own but I prefer using UIViewController containment. That way the child VC automatically has a reference to its parentViewController if needed and can react to appearance/disappearance etc. I only use custom UIViews for dumb reusable UI elements. – johnpatrickmorgan Aug 22 '15 at 12:35
  • I don't use storyboards or xib so everything I have is smart reusable UI elements – Esqarrouth Aug 22 '15 at 12:37
0

There is no harm to have UIViewController reference inside a UIView, unless its creating a strong retain cycle, where ViewController pointing to View with strong reference and view is pointing back to ViewController with strong reference as well, this is not specific to viewController and view but it could happen with any two objects, and in this case it both objects will not get dealloc and its a memory leak. Other then this there is no problem, in your case its keeping reference to viewController because it is using viewController's view as subView and which is fine.

But best practice is that keep your business logic away from view and avoid tight coupling, in an MVC environment view should not have any business logic, controller should handle that, I would say above code is not very good way to work and is not following MVC properly and is tightly coupled.

Adnan Aftab
  • 14,377
  • 4
  • 45
  • 54
  • 1
    Thanks for the response. I have edited this comment because I wrote it before your edit came through. Yeah that makes sense. It seems fundamentally broken. – pls Aug 22 '15 at 12:20
  • 1
    There is plenty of harm. No view should ever have a reference to a view controller. At least not directly. Once you code a view to know about a view controller you are doing things incorrectly. It causes terrible coupling issues. A view should stand on its own and be usable by any view controller or parent view. If you do anything, the view should have a delegate property and define its own protocol. Think of `UITableView` and its `delegate` and `dataSource` properties and associated protocols. Note how `UITableView` knows nothing about any view controller. – rmaddy Aug 22 '15 at 17:01
  • That what I said, what I mean by no harm is that it will compile and if its not creating a retain cycle then it will be okay and will not have memory leak, but its against basic concepts of MVC, – Adnan Aftab Aug 22 '15 at 17:08