UiButton click doesnt work on UIView - objective-c

I have a UIView which is added to Page View Controller. This UIView have a multiple buttons which are tied to an action defined in the controller. At runtime, these views get added to Page View Controller. The problem i am seeing is after loading the page view controller, when i click on the first button. It works fine. But the rest two buttons doesn't. I made sure that the User Interaction is enabled and it is linked to IBAction. Don't know what is causing this issue.

UIButtons are usually unresponsive if their superview userInteractionEnabled property is set to NO or if they are outside of their superview's bounds. The fact that only two of the buttons are not working, makes me think that the latter is the cause of the issue. Set the background color of the superview, run the app and check that the buttons are within their superview's bounds. If they aren't, move them inside the bounds or increase the superview's frame size in order to fit them in.

Related

How do automatically resize an NSPopover with auto layout

I currently have an NSPopover subclass which sets it content view controller to a custom NSViewController meant to represent a tab view:
self.popover.contentViewController = tabViewController;
self.popover.animates = YES;
I'm rolling my own "tab view controller" because I've heard that NSTabViewController doesn't play well with animations. I'd like to use auto layout so I don't think I want to mess around with the popover's contentSize property. When I change tabs the popover correctly changes its size, however, it doesn't animate the change. Furthermore, I have a cross-fade animation that occurs when the tab view switches and the popover doesn't resize until after the animation finishes.
First, I'd like to figure out how to get the popover resize to animate and then I'll worry about getting the animation in sync.
Thanks

NSScrollView documentView cannot be scrolled

Coming from an iOS background, I presumed that NSScrollView would work out of the box, and I presumed that contentSize would reflect the size of the documentView passed to it. This is not the case, if the NSScrollView is created programmatically.
First issue was: why does contentSize not update when a document view is passed in.
Second issue was: why can I not scroll the scroll view, despite the fact there was more content.
The answer to the first question appears to be: don't look at contentSize, look instead at [[scrollView contentView] documentRect].
The answer to the second is that you have to explicitly set hasVerticalScroller and/or hasHorizontalScroller. The scroll view will then dynamically create NSScroller views.
You can also use setAutohidesScrollers:YES to make those appear only when necessary.

UIScrollView with controls repeating on every page?

I have perfectly working UIPageControl. I would like to add paging by swipe, and as I understood, it is done by UIScrollView.
But all tutorials are done with images, I want to have controls (labels, buttons) repeating on every page.
Because UIScrollControl is working the way that it must have set its width * pages count, does it mean, that controls can be placed only in code, not in IB?
Should I place labels and buttons directly on UIScrollView?
Thanks
If you have a View Controller designed using IB with all its buttons and labels, then it is possible to add that View Controller as a subview of your UIScrollView as such:
[scrollView addSubview:controller.view];
scrollView being your UIScrollView and controller being your IB designed View Controller.
You can achieve repeating controls with pagecontroll by using IB by ordering the objects appropriately. Here's what I have:
Drag the UIScrollview to the ViewController and also the drag the Page Controller and other controls also to the ViewController but not onto the UIScrollView. Keep them separate. The objects on the bottom of the IB list of objects shows up at the top of the view stack. (So when you swipe new pages the controls dont move and isn't covered by the UIScrollView) I also group the various controls by group selecting them and then use the "embed with view" menu item so that in IB I have two groups, the controls and the UIScrollView. Makes it neater and easier to manage. As for changing labels, I haven't tried it but I've seen tutorials where you can have iboutlets linked to changing value of pagecontroller and then update the labels in uiscrollview appropriately.

Only subviews added in viewDidLoad automatically resize

I've created a custom subclass of UIViewController that acts like a UINavigationController or a UITabBarController. Let's call it a ToolbarNavController. It has a toolbar at the bottom with controls for the user to move to a different content view.
I have two content views aside from the ToolbarNavController's view. Both are loaded from a nib and have their own controllers. The app starts out showing one of them. A button in the toolbar allows the user to switch between them.
When I add these views as subviews of the ToolbarNavController's views in viewDidLoad, they are correctly resized to fill the area between the status bar and the toolbar without overlap/underlap.
But when I try to lazy load the second view, adding it as a subview for the first time only when the user presses the toolbar button, iOS does not resize the view to account for the toolbar in its parent view, and it underlaps the toolbar which messes up my Autolayout constraints. Also, when I don't add the subview in viewDidLoad, if I put the device in landscape orientation before switching to the second view, it loads with a portrait orientation frame.
Bottom line: When inserting a subview in viewDidLoad, iOS sizes it correctly and manages autorotation for it. When inserting it later, I need to detect orientation set the frame myself. (And for some reason when I do this, autorotation kicks in again).
What is going on?
In viewDidLoad, the view is not yet layout for the resolution and interface orientation, and view properties are as they were in the interface designer. So, if you had a portrait view, that is how the initial properties of the view are set when going into viewDidLoad. When you add your view there, you add it to the XIB view. Later, iOS performs layout on the view hierarchy and thus resizes your inserted view as needed. But when adding your view at a later point, the view hierarchy has already been layout, so it is expected that the new view you are adding is also layout correctly.
Best practice is to calculate the size you need using the size of the view you are inserting into. For example, half the width of the containing view, or third the bounds, etc. This way it is independent on the orientation the interface is in.

Prevent UITableView from scrolling when custom subview is handling touches

In my iOS app have a UITableView which contains a custom subview in one of it's cells. This cell is an interactive view that handles touch events (touchesBegan, touchesEnded, touchesMoved) to update itself.
The problem is that when the user 'drags' up or down, the tableView catches these touches (although I don't pass the touches up the responder chain), scrolls the table and prevents the subview from working correctly. I would like to prevent the table from scrolling as long as the user is touching that particular subview.
The subview has no reference at all to the tableView.
How can I prevent the scrolling behavior of the table?
Update
Despite accepting the answer below, I ended up handling my situation differently. I handle the touch events in my custom view now, pass them up the responder chain (to the table cell), the cell handles the touch events as well, using them to enable/disable scrolling on the superview (the table).
Turning off "Cancellable Content Touches" in the UITableView solved this for me (in the UITableView attributes inspector under Scroll View / Touch). I got this from this SO question: Scrolling a UITableView inside a UIScrollView
From the UIScrollView:canCancelContentTouches doc:
If the value of this property is NO, the scroll view does not scroll
regardless of finger movement once the content view starts tracking.
The most common method I use in such cases is to delegate information up the event chain. Set delegates in manner:
subview->cell->table
The second thing you can do is to send a notification via Notificaion Center. Table would listen to any events that forbid normal scrolling. It is overshoot but it will leave your code consistent.
I have no more ideas at the moment.