Where to put programatic constraints for MVC - ios

I want to practice creating simple apps using no storyboard. I am able to do the constraints programmatically (slowly) but I want to also practice separating my code into MVC. Is there a particular place/method that I am supposed to write the programatic constraints? Or does it not matter?

Good discussion in the comments. My thoughts, based on that discussion?
With an understanding that the question is subjective, you place your constraints:
The earliest in a view controller's life cycle where they work.
As "close" to the view as possible.
If it's something common, make it as universal as possible.
Understand how your specifics fit into everything.
(Understand, the question isn't limited to constraints. It could apply to hierarchies, UI, even database tables when you get down to it!)
Sticking to constraints, and my answer....
(1) Use the UIViewController and UIView lifecycles.
Generally the view life cycle is loadView, viewDidLoad, viewWillAppear, viewWillLayoutSubviews, viewDidLayoutSubviews, and viewDidAppear. great SO answer detailing this.
I believe that loadView is too early for constraints, but not viewDidLoad - **provided you aren't expecting to know the frame size. While many say viewDidLayoutSubviews is the right place for that, I've found that viewWillLayoutSubviews most times works just as well. Either way, get your constraints set as soon as possible!
(2) Do it as close to the view as possible.
If you have subviews - I have a "ToolBar" class of objects - you want the constraints, at least as much as possible, to be coded inside the class. For instance, in my tool bar, it slides out, has buttons, and even rotates upon orientation. The only constraints not inside these classes is for orientation - that owner is (and I believe should be) the view controller instantiating it.
(3) Make it universal.
I plan to use this tool bar across a few apps. So the first thing I did was add it to a framework. This framework was needed because I had an app that I delivered a photo editing exension - and the "edit" screen is as much the same as possible. In the end I move all my constraints there. (At least as much as possible.) Anything that I believe is reusable.
(4) Understand the specific requirements of your app.
This should be obvious. If you need to code for various orientations, use arrays and activate/deactivate them. (YES, a common mistake is replacing them! That's setting yourself up for some major headaches.)
If you can keep things active, declare the constraint, set `isActive = true1, and forget about it. If you need to adjust that constraint's constant or multiplier, in the declaration name it and then where you need to alter it, do it.
My conclusion? Auto layout is a very useful tool - more so in code. But the placement of code is like asking "how does one code an OOP app for auto rentals" or " how does one design a database for auto rentals". It not just an art, there are many answers. These are the "rules" I try to follow - YMMV.

To get started with this style of development I recommend checking out Let's Build That App as he goes through very in-depth examples of setting up complex apps entirely in code, without storyboards.
The way he structures the constraints is using a custom implementation of UIView, that way your view code is separated from the ViewController. Then, in the viewDidLoad method you can instantiate your implementation of UIView with something like self.view = MyView().
I wrote a few apps like this. The major drawbacks are that it can become very difficult to make quick adjustments, and you really need to learn about all the different types of constraints you can use.
Here's a pastebin of some extensions I used when doing this. I hope this helps.

Related

loadview VS interface builder

Since I've seen many other IOS projects written in obj-C, I found that many of them do not use interface builder or storyboard file. It's hard to see what's going on. And I've known that loadview method should do the things similarly to drag and drop objects in IB. So what is the difference between loadview method and doing some dragging objects in interface builder?
Well, you don't have AutoLayout (unless you use hard code to constraints too) and Size Classes without interface builder.
Working with IB is much less coding and more clarity.
If you add a Label to IB then the IB is responsible to release that object. And it's added to the view of course so you don't have to.
I would never go without IB now and would recommend to do so for other devs.
I use Size Classes + AutoLayout and all my screens looks good on every device plus that iOS9 is coming out: I have multiple screens auto enabled because I used Size Classes. App works without maintenance for many years..
Simple difference between IB and loadView
IB:
All u can do is drag and drop things without having any code written.
loadView:
It is first viewCycle method which calls on loading any view of corresponding viewcotroller, You should do all your stuff programmatically here. like adding subviews to your view. and adding constraints etc.
Thanks

Using custom NSView/UIView subclass from XIB?

OK, this may sound very basic (especially for someone who has written tens of thousands of Objective-C code), but I've always tried to avoid all this... or just tweak existing solutions. The result? I've never learnt how to do something simple like that.
So, here's my ultra-simple scenario:
I want to create a custom NSView (let's say a simple view with an image and a text in it), which I'll be able to assign in the Interface Builder (take an NSView element and set its class to MYCustomView - that's all - nothing more complicated)
I know I can write an NSView subclass and have it draw all my elements programmatically in drawRect: and all this - but I most definitely don't find any point in that.
What I do want is to simply draw the view in the Interface Builder (in our example, with a "placeholder" image and textfield), be able to use it as the "basis" of our NSView subclass, and also maintain pointers to the two elements in the view so that I can programmatically access them.
I know it's doable - I'm not asking about that. What I need is an ultra-simple walkthrough. Is there anything you can point me to?
Rephrasing the question in a... one-liner:
How can I replace the programmatic approach (seen in like 99.9% of NSView subclasses) in drawRect:, with a layout taken from a XIB?
P.S.
(A) Trust me, it must have been the 100th time I've been reading about NSViewControllers and all these, but not having used them, probably means that I still haven't found the point in using them...
(B) Please, don't shoot me with "what have you tried" questions. In the course of time, I've tried loads of things and at times I've somehow made it. However, it always feels like a crappy, messed up thing I just managed to get working. Nothing more, nothing less. All I want is to know if there is a simple tutorial on the above simple scenario.
(C) If I get an actual explanatory answer to this one, I guarantee I'll re-post it myself. You simply can't believe how many seasoned Cocoa developers have serious trouble dealing with this...
I've always wanted "custom" Storyboard classes as well!
This may not totally answer your question but this is just how we do it now, in iOS: just use container views.
Full extremely long tutorial: https://stackoverflow.com/a/23403979/294884
Everything's a container view in iOS now.
What we do is just have a scene, and then duplicate it: then change the colors or whatever as you describe.
Here's a literal example from the storyboard that was open behind this browser window!
Notice the small class/scene thing, we just copy it. Notice in the example it is slightly customised, just as you say. They are all the same class (it happens to be caled "BookBist") {"bist" == "bouncy list" btw}
Then as I say container views are the secret because, well, it's for exactly this purpose, it's why apple finally introduced "container views".
(BTW on that long container view tutorial. Search down to What if you want (say) a table controller or a page view controller instead of a UIViewController? it's a critical trick when making container views! Ridiculously Apple gives you a "default" VC when you drag in a container view; of course you never want that; in the example at hand I put the small BookBist scenes connected to the container views wherever they are needed.) Example...
Now, I 10000% understand what you are asking and have always wanted to know the answer myself!
For use HALF the answer, is, as I say, "copy the scene" so that works perfectly in modern storyboard. I appreciate that sucks, because what you want is a prefab, like in any game engine such as Unity3D, right? Me too!
But do note that THE OTHER HALF of your answer is certainly "container view magic" - "everything's" a container view now in iOS, indeed Apple finally put them in to make a rational way to do exactly the sort of thing you describe.

Design iOS View in Code without storyboard

I want to design and generate view elements in code, without using storyboard. But I haven't figure out a simple way to locate where should I put my view elements by describing its CGRect. For example, I can drag a button direct into the storyboard and put it where i want, however, in code, I have to write something like
[button setFrame:CGRectMake(24.0f, 113.0f, 271.0f, 140.0f)];
Is there any way or any software can help me?
Your question is a bit broad. You can create your view in code by including in your subclass of UIViewController properties for each subview (control) element and then make all the initialisation in designated initialiser and setting frames and other customisation in viewDidLoad method most likely. But for details where to what set you should go to references for UIViewController lifecycle as it may depend on what you want to achieve. in some cases setting frames in viewDidLoad will be fine whereas sometimes you will need to make some changes in viewDidLayoutSubviews for example.

how to detect interface changes on iOS application

Is there any possible way to detect every change on User Interface during runtime??
I'm trying to find all objects in the current app interface.
I'm trying to to get all nodes inspecting recursively the main Window, but, for example, how to know if the top viewcontroller changes or if it's added a uiview dynamically, or is presented a modalview??
The main objective is to have a library to do this..
Any idea, help?
Thanks!
You could write your own library based on this, using advanced Objective-C techniques. I do not recommend you to do this, since it mostly breaks MVC patterns on iOS. Depends on what do you want to use it for, maybe analytics?
So these are the options I believe, if you want to actively inspect UIView hierarchy. All options are pretty complicated though.
Swizzle methods such as addSubview and removeFromSuperview of UIView, so you could know when changes like that happens. Including the getters of frame and bounds, if you wish to know the position.
You could use KVO to watch properties such as: subviews, frame, bounds, superview to notice any changes. But at one point you would have to add the same object as the observer (could be singleton).
Decide for an interval that is fired by a NSTimer and go through the hierarchy recursively beginning at keyWindow on UIApplication. This would have a big performance impact though.
There may be other options, but these are the ones I believe to be the best choices.

iOS: create a XIB from a UIView

I have lots of Views in old projects that I have layed out in code, using absolute positioning. That code is really hard to maintain. I'd like to port the code to using interface builder, but I'd have to layout every view again by hand.
Is it possible to programmatically create a XIB file from an existing UIView (which has been created programmatically)? I have searched the docs but can't find anything.
XIBs are essentially XML files, I guess that if you inspect a few you'd understand the format for different controls, but that would need a lot of manual reading, writing & testing to complete for all views. Probably a better plan would be to start slowly migrating to IB-made views.
Yes, it's possible; however, the thing is, you need to set all essential controls and properties of your xib. You won't be able to see its actual look and feel unless you have executed the project in your simulator or on an actual device (that means hard code everything).
You would use loadview in initializing your xib. Here's a bit of it:
- (void)loadview{
// set your view, screen size, and other properties of your xib
}

Resources