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.
Related
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
I understand that viewWillAppear will be called when duh.... when the the view is about to appear.
But how does IOS know that a controller's view is about to appear?
When exactly that and how it is implemented?
For example, does the childController.view check first that window is one of it's super ancestors? Does the view has a pointer to it's controller? How exactly that works? Does everytime a view is added it check whether it's window is it's super ancestor and whether it is the view outlet of a UIViewController?
For example, if I add childcontroller.view but not to a subview of any view that's being called. Will viewWillAppear called?
Does the childController need to be the a child of a parentController so that viewWillAppear of the childController will be called when the parentController's viewWillAppear is called automatically?
The view is loaded by your controller using the - (void)loadView method. This method is implemented to load a blank view or a view from a nib/storyboard. You only need to override it if you really need to create a view hierarchy from scratch.
All of the magic happens when the value of the view property is first requested and the controller detects the value is nil. All of the life cycle method calls are handled by the UIViewController. There is nothing you need to do other than implement the methods if you need them. Remember one thing: There is no guarantee the view has been loaded until the - (void)viewDidLoad method has been called.
Everything I've learned about controllers how they work has come from the View Controller Programming Guide.
The structure of my MainStoryboard is:
->Tab Bar Controller -> Navigation Controller -> View Controller (Search)
The behaviour I want to have is that when the user re-selects the Search tab, the UIScrollView on it scrolls to the top. I am unsure how to get the event from the TabBarController, however.
I've been looking at a lot of stuff about UITabBarDelegate, particularly:
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
I have, not quite managed to get this to work properly though. I am very unsure about how to go about setting the delegate (assuming that is the way it's done). I've tried hooking it up in IB, but it wouldn't let me. I also tried to get the UITabBar from the AppDelegate (after looking at some seemingly-related answers).
Any pointers will be greatly appreciated (unless they're null).
UITabBar *aTabBar = [UITabBarItem alloc] init];
....Any other modifications you want to make to aTabBar....
[aTabBar setDelegate:self]
Don't forget to add "<UITabBarDelegate>" to the "#interface" part of whatever object you're trying to designate as the delegate.
For my own code, I usually use some object that isn't the application delegate (as the app delegate is usually meant for application level events like "application is suspending" or "application is coming back into foreground"). If you add "<UITabBarDelegate>" to your Search view controller, make sure that whatever you do with the "didSelectItem" method is applicable only to the Search view controller. Otherwise instantiate some different object if you want to do actions on various view controllers based on which tab bar item is being displayed.
I have a customized View Controller (we'll call it the wrapper). Its view contains only a UIScrollView. The scroll view contains another customized view controller (we'll call it the inside view), initialized from an xib file (the scroll view itself is initialized from a xib file as well, but I don't believe it matters).
The wrapper view is displayed using a UITabBarController, which contains several more similar view controllers.
I have this weird problem: the wrapper's rotation functions - shouldAutoRotate, willAnimateRotation - get called every time that I rotate the device. For some reason, the inside view's rotation functions don't get called, but it still rotates. The inside view's shouldAutoRotate does get called when initializing it (when the app starts).
I've looked at google and couldn't find anything that is relevant to my case. I'm not sure if it is related, but the Autoresize subviews is checked on all xib files.
I'd be glad if you could help me solve this problem. I need the inside view's rotation function to get called on rotation in order to arrange it manually, but I'd like to avoid calling them from the wrapping view (rather it to work as it should).
Thank you in advance!
Well the innerViewController's rotation function will not be called because they are added as subview's to your scrollView what you can do is generate a NSNotification when orientation changes in your parent controller then you can receieve notification in subview and manage them accordingly. Or you can iterate through subviews of UIScrollView when your shouldAutoRoatate called in you parent controller and then manually call should autorotate method of child views. Hope you understand.
The simplest way is to hold some UIInnerViewController* innerController in your .h file and in .m to call inner's
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation inside of the wrapper like so:
wrapper.m
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
BOOL innerResult = [innerController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
//may be more computations here
return innerResult;// or any other value, based on your needs
}
Other approach that you may use is to register inner controller to UIDeviceOrientationDidChangeNotification like so:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
and layout subviews in -(void)orientationChanged:(NSNotification*)notification;in the same inner controller. The only thing you should be awere of, is that UIDeviceOrientation is a little-bit different than UIInterfaceOrientation and may hold value such UIDeviceOrientationFaceUp that is not applicable to UI changes in most cases.
Nesting viewcontrollers inside custom viewcontrollers is not supported in iOS 4. You can usually forward all the necessary messages to your child VC's manually, though, with acceptable results.
I am trying to detect touches, but the touchesBegan method is not being called.
In my ViewController, I have added the touchesBegan method. My Nib files owner is set to the correct V.C. The Nib itself consists of the view, with a scroll view and a tab bar. Nested in the scroll view is an image view, which has user interaction enabled. What is precluding touches from being registered, or preventing my implementation of touchesBegan from being called?
I've scoured the Internet and Apple docs, and I can't see what I am doing wrong. Also, I'm not really sure what code I can post here to help with my query. Thanks.
Okay, after a lot more reading, I've now got a scrollview and a imageview, both of which are created programatically. The imageview is a sub view of the scrollview, and scrollview has been subclassed so that the touches ended method can decide whether it was a single touch, in which case call the touches ended method from the view controller, otherwise call its supers method. This works just fine, however, why is it that this cannot be done without subclassing scrollview? Is it my lack of understanding of how scrollview works, or is it just a limitation of it?