NSSplitViewController in OSX 10.10 using Xcode 6 - objective-c

According to documentation on NSSplitViewControllers, the associated NSSplitView uses the NSSplitViewController as its delegate. Specifically in the documentation, "The split view controller serves as the delegate of its split view object (the object that manages the dividers). If you override a split view delegate method, your override must call super."
I have implemented an NSSplitViewController in interface builder and gave it a class. However, none of the splitView delegates are ever invoked. Additionally, if I just do something like spit who the splitView delegate [ NSLog (#"%#", self.splitView.delegate); ], the result is "null". If, however, I assign the delegate either in IB itself (by dragging the delegate outlet to the NSSplitViewController) or inside code ([self.splitView setDelegate:self];), I get the following error:
An uncaught exception was raised
SplitViewController's splitView is unable to use autolayout because the SplitViewController overrides an incompatible delegate method.
I'm completely flummoxed.

If the delegate of a split view implements one of the following methods, it becomes incompatible with auto layout.
splitView:constrainMinCoordinate:ofSubviewAt:
splitView:constrainMaxCoordinate:ofSubviewAt:
splitView:resizeSubviewsWithOldSize:
splitView:shouldAdjustSizeOfSubview:
https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/#10_8AutoLayout
And because NSSplitViewController requires the use of auto layout (mentioned in the documentation), these methods are incompatible with NSSplitViewController and shouldn't be implemented in a subclass.

Extending on Taylor's answer.
In macOS 10.8 Apple made improvements to NSSplitview, which includes respecting constraints of the subviews. Apple also introduced holding priority for subviews of NSSplitview. Holding Priority is the priority of holding the size of the subview, so while resizing the splitview, subview with the lowest priority will resize first.
So to control the resizing behavior you will have to tune the holding priority of SplitView Items. This can also be done in storyboard directly

Related

What's the advantage of using UIViewController as owner of xib?

Most of the time, owners of xib is a UIViewController.
I sort of use it my self.
Still I am confused why.
I suppose, the viewDidLoad and viewWillAppear is kind of the main selling point.
Is that it?
What are the advantage of using UIViewController as owners of an XIB?
A UIViewController object is the main way for views to appear within an iOS window.
Apple provides this as a fundamental, foundational building block (along with so many others) which you can use to build upon quickly and get your app out to market.
And when you subclass UIViewController, you're able to do lots of beautiful customizations which can be collected and eventually turned into (hopefully decent) products. When you subclass a UIViewController, you need to set the "owner" of a XIB file to that subclassed view controller (e.g. ThioViewController), so that way the app knows what object (and user interface) is being instantiated.
Hopefully this isn't too super abstract of an explanation.
First, spend a bit time to understand MVC http://en.wikipedia.org/wiki/Model–view–controller
This is the milestone of Objective-C (not only) development.
UIViewController is controller for all your views (inside this viewController). It provide starting point for you to create views on the screen, manipulate the views, handle actions from views etc.
You can create UIViewController programmatically.
XIB is representation of the screen which you can comfortably operate in Interface Builder to create and customize design of your application screen or one of the screens.
Since XIB represent the screen(view) it must be the controller which controls all the view on the screen - UIViewController or UINavigationController or other type of controller depending of your needs.
Most of time you will subclass UIViewController and use it to achieve you goals.
UIViewController have several subclasses which inherit directly from it (UINavigationController, UITabBarController).
Also UIViewController hav several methods (some of them)
-(void)viewDidLoad
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
and
-(void)viewWillAppear:(BOOL)animated
Parameters
animated
If YES, the view is being added to the window using an animation.
Discussion
This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.
Please check Apple documentation for more information
https://developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html

UIScrollViewDelegate scrollViewWillEndDragging:withVelocity:targetContentOffset: warning

I have two UITableViews on one view controller (view controller is their delegate). One of them will be depending on scrollViewWillEndDragging:withVelocity:targetContentOffset: (I want to do some kind of custom pagination). The other one have pagingEnabled property set to YES and when I try to scroll it for the first time XCode gives me warning
2012-09-07 16:46:39.672 test[17393:707] Stop offset can not be modified for paging scroll views
even though the code of the method is at the moment:
-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
return;
}
When I delethe the method scrollViewWillEndDragging:withVelocity:targetContentOffset: everything seems to be all right. Do I need to try to make another delegate (without that method) and make it UITableView with pagination delegate, or should I just don't worry?
The reason that you are seeing this warning in the console is because the method scrollViewWillEndDragging:withVelocity:targetContentOffset: has no effect when the scroll view has paging enabled. The documentation states the following.
This method is not called when the value of the scroll view’s pagingEnabled property is YES.
In other words, Xcode gives you a warning, but, as #tiguero indicates, it is best to check in each delegate method which table view (scroll view) is sending the delegate message.
As for the warning, you can ignore this warning since your controller is the delegate of both table views, one of which has paging enabled.
I am a bit confused about what you are trying to achieve here. Nevertheless if you have the same view controller that act as a delegate for two UITableViews, I recommend to have those delegate methods implemented and check which scrollView you are working on by checking the scrollView variable passed in parameter of your delegate method.

UIView subviews's layout update

In the viewWillAppear delegate method, I'm setting subview's frames with rects ( location and size).
Now, There is one subview whose content will grow with user actions.
So, I need a callback in that superview controller ( The One I am talking on first sentence) , to update the layout. In this callback, I can find out how much the size increased, and then set other subviews frame rects too.
It can be done through calling setNeedsLayout method on the view, but it requires layoutSubviews to be overridden on the UIView. Please note that it is not a delegate method, I need to have a custom view, Which I don't want to do,
Is there any delegate method for me to update the layout in the view's controller ?
UPDATE:
This need to be support on iOS 4.2
There are two UIViewController methods of possible relevance:
-viewWillLayoutSubviews
-viewDidLayoutSubviews
You can probably guess when they're called.

The relationship between UIViewController and UIView

I'm trying to understand how these two are connected. Every time you make a UIViewController does it also automatically come with its own UIView?
Also are these from Cocoa or Objective-C?
UIViewController is a Cocoa Touch class built for the purpose of managing UIViews. It expects to have a view hierarchy, but you don't "automatically" get a view (this is slightly inaccurate; see edit below). Usually you will obtain views by calling initWithNibName on your view controller.
There is some built-in magic in Interface Builder which knows that if File's Owner is a UIViewController (or subclass), there is a property called view. That's about it.
Once you have linked a view controller and a view, the view controller does a fair amount of work for you: it registers as a responder for view touch events, registers for device rotation notifications (and handles them automatically, if you wish), helps you take care of some of the details of animation, and handles low-memory conditions semi-automatically.
Edit: correction—if you don't call initWithNibName or set the view property manually, the view property getter will invoke loadView if view is nil. The default implementation of loadView will see if you've set nibBundle and nibName and attempt to load the view from there (which is why you don't have to call initWithNibName, most of the time), but if those properties aren't set, it will instantiate a UIView object with default values. So technically, yes, it does automatically come with its own UIView, but most of the time that's of little value.
UIViewController doesn't automatically come with a view. You have to make a view in the -loadView method. By default, this loads the view from the nib file you've specified. You can also override this method to make a custom view if you prefer not to use a nib.
Also, the view is not created right when the UIViewController is created. UIViewController uses a technique known as lazy-loading to defer the creation of a view until the view is actually accessed for the first time.

UIScrollView calls layoutSubviews() each time its scrolled

I subclassed UIScrollView (IPhone SDK) and overrode the (void)layoutSubviews; method.
I noticed that each time the scrollView is scrolled, this method is called.
Is that the correct behaviour or do I have mistakes in my code? If it is the default behaviour, isn't this a performance killer?
Sincerely,
heinrich
It is the correct behaviour and it should be used to get a custom layout of your subviews. I have used it several times and haven't had any performance issues eaven with hundreds of items added.
A cut-out from the documentation on that topic:
Subclasses can also be containers for
other views. In this case, just
override the designated initializer,
initWithFrame:, to create a view
hierarchy. If you want to
programmatically force the layout of
subviews before drawing, send
setNeedsLayout to the view. Then when
layoutIfNeeded is invoked, the
layoutSubviews method is invoked just
before displaying. Subclasses should
override layoutSubviews to perform
any custom arrangement of subviews.