UISwitch not responsive in UIScrollView - objective-c

I'v encountered strange bug, and have no idea why this happens.
I have UIScrollView, in it I have 12 views. Most of them contain UISwitch button and a label. Size of views are dynamic (depending on the lenght of label.text). Everything works and shows, except two views on the bottom. They do get shown, initialize as expected. Yet UISwitches in them do not work, clicking or touching them does not do anything. Both of them are no exception to others (all of them are copy paste). I have double checked IBOutlets, they are fine. I have suspicion something is wrong with scrollView. Maybe beyond some point it doesn't recieve inputs anymore? Eventhough I can scroll up and down and everything is shown just as expected.
Any ideas what to check ?
I have switched these two views with first ones. And more bottom views get unresponsive, like there is a line, beyond which ui is not responsive. Ideas?

You say the switch is in a view (one of 12) and that view is on the scroll view,
maybe the UISwitch is out of the view bounds? Try to set that views .clipsToBounds = YES;, can you still see the switch? If no, it means the switch is out of bounds therefor you gat no touch events. Make that view larger to fix that.

Check correctly. if the UISwitch and UIscrollview user interaction are enabled.
Check whether the UISwitch is added within the UIscrollview's frame.

Related

NSCollectionView loses scrollbars after changing minItemSize until view gets resized

I have an NSCollectionView with a vertical NSCollectionViewFlowLayout. I display rectangular icons in it.
I also have a slider in the UI, and when that changes, I adjust the minItemSize, which I then use in collectionView:itemForRepresentedObjectAtIndexPath: to create an equally sized NSImageView to the returned NSCollectionViewItem's imageView. Then I reload the view by invoking reloadData.
After that, the view shows the icons in the new size as intended.
The problem is, provided I have more data to show than fits into the current scoll view, that when the General System Preferences are set to Show scroll bars: When scrolling, the scrollbar disappears after reloading the collection view, and trying to scroll with the trackpad leads to a bounce that's telling me that the scroll view thinks that the content is just what's visible, nothing more to scroll.
But as soon as I resize the window, which also resizes the collection view inside, the scrollbars come back.
Curiously, if the System Prefs are set to Show scroll bars: Always, then the issue does not appear and the scrolling always works, and the scrollbars always remain visible.
I've tried a lot of things to trigger the re-calculation of the scroll view, such as invalidating the layout of the collection view's layout, the scroll view itself, its content view, and also tried to set their needsLayout to true. Nothing makes this work.
Update: The potential duplicate (NSCollectionView does not scroll items past initial visible rect), neither the collectionView.setFrameSize: nor the window.setFrame: suggestions work for my case (I tried adding these line before and after reloadData).
Even if I force a resize of the window like this, it doesn't bring the scrollbars back, only a manual dragging of the window edges does:
[self.collectionView.window setFrame:NSInsetRect(self.view.window.frame, 1, 1) display:YES];
Also note that in my case, initially the scrolling works, just not after resizing and reloading.
Another finding: When I call selectItemsAtIndexPaths:scrollPosition: after reloadData, then the scrollbar comes back. But only if I pass a non-empty NSSet for the paths. And since I may not have selected any items, this isn't a permanent solution.
If no other ideas come up, I'll try to make a demo project.
I've solved it:
I had to delay the call to reloadData, e.g. by calling it from within the block code of dispatch_async(dispatch_get_main_queue(), ^{ ... });
Before the fix, I did call reloadData right from the setSliderValue: handler, which is bound to the slider's value. It appears that this didn't go well together.

weird gap when using uiscrollview and uilabel

here is the problem i have a tow muti-line label with many content, so I use a scroll view to show them all
then I follow this to do the autolayout: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html#//apple_ref/doc/uid/TP40010853-CH5-SW2
basic idea is to make a container view outside the scroll view to make sure the labels can fill the scroll view no matter what direction it is.
here is the hierarchy and constraint:
and the portrait mode works well:
but when it change to landscape mode some wired gap pops up!
and the more text i put in the label the higher gap i got!
my question is what should i do to kill those gap?
please give me some explicit solution or just give me an example, thank you!
and i am using autolayout in ios7, so some solution without coding are preferred!

Strange UIContainerView autolayout rotation behavior

I have a view controller that consists of two child UIContainerViews, one of which is fixed-width, and the other which dynamically adjusts its width based on portrait vs landscape mode. Both contain UITableViews.
For some reason, if the screen loads in portrait orientation it renders fine. However if it loads in landscape and then rotates to portrait, the second (dynamic) table gets all screwy and thinks it's wider than it is/should be, letting you scroll it horizontally which it should not be doing.
The cells of the tableView all size properly and stick to the left side of this "too wide" tableView. However, if I color the background of the tableview pink, I can see the whole thing is extending into this too wide zone.
It's baffling me what's going on here. Shouldn't autolayout be the same regardless of which orientation the view controller was loaded as?
If I log the widths in a viewDidRotate... handler, everything appears to have the correct width, yet it's still rendering in this bizarre way.
Is there perhaps I way I can just force the container view to re-lay it self out?
Update: It is the contentSize of the tableView that is getting messed up. All the other widths are correct when logged, but the contentSize.width is way off. The good news is I can just manually set this back to what it should be and everything works great! However it doesn't answer the question as to why it's happening in the first place or what I'm doing wrong (if anything).
Here's a screenshot:
In order to force a UITableView to (re)calculate its content size, you may use layoutIfNeeded method. It traverses through the view hierarchy and lays out the subviews immediately, so content size is set properly.
Instead of setting the size manually, call this method for your table view.

What is the best way to create a composite scrollable view on iOS

I need to create a scrollable composite view on iOS. That is to say, the view will contain at least one image, possibly a button, and some text (that we may wish to format with bold fonts, etc). The amount of data, and particularly the amount of text, is variable, from maybe 4 lines to maybe 100. The data is "variable" to a degree, and in particular the image and text do not come joined at the hip.
This all needs to fit in a "pane" of about 280h x 115w pixels in a portrait-only layout.
A single UITextView doesn't provide the facilities to display an image or format the text.
A UIWebView provides the ability to display the image and formatted text, but the button is a problem (not even sure if it's doable).
A UIScrollView would easily allow the image and button, and then a UIWebView could be embedded in the scroll view for the text, but then scrolling becomes a problem -- I'd like the entire view to scroll as one, without having to resize the web view to contain it's content, and without the confusion of a scrollable within a scrollable (the doc warns of "unexpected behavior").
(I'm guessing your thoughts at this point are that I want too much.)
So, any suggestions? What's the best way to get close to what I need here?
In iOS5 the UIWebView has a scrollView property, which is a normal UIScrollView. You should be able to add a UIButton as a subview of the scrollView to achieve what you want, although positioning it correctly may be a challenge. Prior to iOS5 you could cycle through the subviews of the UIWebView to find the UIScrollView with isKindOfClass...
I suggest testing with a UIWebView inside your UIScrollView. I don't see any interference in the iOS 5.0 simulator. I don't know if there are problems in iOS 4.0.
If you find that there is interference, you can prevent it by setting the web view's userInteractionEnabled property to NO, either in the nib or in code. This will prevent the web view from receiving any touches, so the user also won't be able to pinch-zoom it, follow links in it, or copy text from it.
In the web view's delegate, implement webViewDidFinishLoad: to set the web view's size and the scroll view's contentSize. For example:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
CGRect frame = self.webView.frame;
frame.size = [self.webView sizeThatFits:CGSizeMake(frame.size.width, HUGE_VALF)];
self.webView.frame = frame;
self.scrollView.contentSize = CGSizeMake(CGRectGetMaxX(frame), CGRectGetMaxY(frame));
}
When I did a similar thing, I had a dozen of views which I added to the UIScrollView and then calculated the frames of all the views. Granted, it was an extremely tedious work, given that some views could get hidden under various conditions. The layout code was actually pretty simple, laying out views from top to bottom, but ugly. The upshot is that it works like a charm, fast and reliably. You can even trivially wrap it in an animation block.

UIPanGestureRecognizer on a view inside of a scroll view works only sporadically when scroll view is zoomed in far

I have a UIPanGestureRecognizer on a view inside of a UIScrollView. Its function is to move its parent view around when panned. This works perfectly well at 1x and 2x zoom resolutions in the scroll view, but zooming in farther causes them to fail quite often - yet not always.
There is also a long press & double tap recognizer on the same view, which both work fine when zoomed in. Overriding the hitTest method on the scroll view shows that the UIGesture view does in fact receive touches when zoomed in (which is expected, given that these other recognizers work.)
I've tried several combinations of cancelContentTouches & other attributes on the scroll view with no success.
Does anyone have any suggestions?
One workaround I've tried: make your PanGesture'd views siblings of the scroll view, and update their position / scale manually via UIScrollViewDelegate didScroll. You will have to take the scroll view's transform into consideration whenever inspecting the PanGesture views, though (such as getting position information).
Obviously this is not ideal - if anyone else still has a better solution, I'd be happy to hear it!