I making an ipad application with screen split in half. Each side contains a container and each container holds UIView.
In the left uiView i have a uiScrollView with multiple elements (customs uiview) inside, like a grid but with scroll, and each element support tap gesture.
When i tap each element they work fine and behave like they are suppose to. lets say they do a NSLog(#"tapped!").
Problem comes when i resize either the entire view that holds the scroll view or the Container like so:
navigationVC.view.frame = CGRectMake(0,0, 338,768);
The tap stops working! But if i resize back to its original frame, tap starts working again.
navigationVC.view.frame = CGRectMake(0,0, originalWidth ,768);
I thought the problem would be the elements re-arrange when i resize the scroll view, but in fact its not.
The frame is being resized when i swipe the entire application either left or right.
EDIT:
Behaviour diagram: http://i.imgur.com/4vKpHLQ.png?1
EDIT2: didnt figure it out yet, but i see now that element bound's are changing when the frame is resized.
Got it!
Problem was that when i resized the scrollView the elements.Bounds where changing too. Then i went digging why... could only be something like a anchor... i then started to change a few properties on my XIB.
Under "Simulated Metrics", changed the "Size" drop-down from "Freeform" (add 150, 45) to "Inferred".
Forced the size on initWithCoder, compiled, and it worked.
Thanks Burhanuddin Sunelwala for trying to debug this with me.
Related
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.
I am trying to initiate a scroll view in my UITextView and even though I seem to have selected the appropriate boxes, I can't seem to get the scrolling working. I have gone through multiple questions similar to this but none seem to have the answer.
I included an image of Xcode below:
Question 2: When I scroll down the majority of my text shows but the scrolling stops with two sentences or so left and I have to scroll down and hold it there to read. Any way I can fix this so it scrolls all the way to the bottom of the text?
Can you check the two boxes: Bounce Horizontally and Bounce Vertically and see what's happening? Sometimes your content are actually way bigger than your view, and they are touching a invisible outer box. If you can see they actually move, that means there is nothing wrong with touch or scroll, is just the view layout problem.
For the content issue, my guess is that the content size is not right, you can programmatically adjust it with textView.frame property, set it to a proper size, such as the frame of the window or the frame of the content, which are CGRect classes. Comment below to see if this can solve your second problem.
The text view will not scroll in storyboard, only the app. And the text view will scroll once the content in the text view exceeds the frame size.
If you're using iOS 7+, you can just turn on auto layout, pin each of the sides of the text view to the edge of its parent view, and it works fine without needing to do anything in code.
I have a NSButton sibling on top of a NSImageView.
Whenever I click the window, there are some rendering issues. It looks like this:
As you can see, the white edges are the problem.
Strangely, this problem even persists if I override drawRect:.
Nothing gets rendered at all, but whenever I click it, those white edges appear.
Also, when the background-image changes, the button gets redrawn and the edges disappear.
Any idea what might cause this?
EDIT
I found out that this actually happens with every single instance of NSView
and it actually clears part of the buffer (you can see the desktop wallpaper):
EDIT 2
I also just found out that this does not happen if I layer-back the windows content-view.
Well, this question was impossible for anyone to answer.
My window had a custom contentView, which was just drawing a view with rounded corners.
Instead of using self.bounds, I used dirtyRect to draw the background.
So when the contentView wanted to redraw the background of the controls that were updated, those rounded corners were cut out.
I have a custom subclass of UIView and a full screen UIButton with a background image on it as you can see in the image,
on the right side, there is a UIView with a UIImageView on it and some other not important labels and buttons. The important part is, there are two scrollviews on that UIView and at the run time, i add UIButtons ( not small ones, 200 x 100 ) on those scrollviews with vertical scrolling enabled.
The situation is really very complex so i will write as items what happens in different conditions. In my application, there are 10 of these complete screens, on a custom subclass of UIView and i use UIPanGestureRecognizer to scroll from one to other.I have a good reason not to use a scrollview for this. All the windows ( the below image, not UIWindow ) populates their content in a loop, so the running code is exact same for all of them and all of them are being created from the same .xib file. And the last information, the bigger UIButton that covers all the window has an action for touchupinside and the smaller buttons in scrollviews have their own touchupinside selectors.
Some of my windows works perfectly, if i touch anywhere on the screen, the bigger buttons action is called, if i touch and drag, the scroll works and i navigate to the next / previous window, if i touch on smaller buttons in scrollviews, their actions fired and lastly i can perfectly scroll within those buttons.
Some of my windows, when i try to scroll the scrollviews, the bigger windows pangesturerecognizer catchs this event not the small scrollviews, and if i touch the small button in that scroll view, the bigger buttons event is fired ( it pass all through uibutton > uiscrollview > uiimageview > uiview to the uibutton at the button like they dont exist )
if i replace the right container view some other position on the big uibutton, it randomly works well or not, sometimes one of the scrollviews works well and the other not.
it has a consistent behaviour, if on a one position, it works, it allways works, and if it not, it never does.
Again, all the views and subclasses have their userinteraction enabled yes, the opposite is already imposible because the behaviour changes only acording to position of container view on the big uibutton and also changes acording to big uibuttons background image.
I've placed a touchesBegan method for just test purposes, when the touches does not work as expected, the event fired with touch.view is the container of the big button, even if i touch on a small button within the scrollviews.
I've spend two days already for that and no result.What can cause this behaviour ?
EDIT : After krumelur's comment I've changed my focus from configuration of those views to animation i give to the container views, and i've noticed that, the problem is about the animation, i'm adding the the code part that animates all ten windows and behaves like a custom scrollview. All windows have their custom layer class and when i catch pangesture recognizer i move windows on the screen with following code. items in that code is an array which holds layers of all the windows. The animation causes that strange situation but i couldnt figure out yet..
- (void)layoutSublayers {
[super layoutSublayers];
[CATransaction begin];
[CATransaction setDisableActions:YES];
float angleDelta = 2 * M_PI / [items count];
float a = angle;
for (UIBaseLayer *l in items) {
l.position = self.position;
CATransform3D translation = CATransform3DMakeTranslation(cosf(a)*(radius.x), 1.0, (sinf(a)*radius.y) - radius.y*1.0);
float dailyAngle = (M_PI_2 - a);
CATransform3D rotation = CATransform3DMakeRotation(dailyAngle, 0, 1.0, 0);
CATransform3D t = CATransform3DConcat(rotation, translation);
l.transform = t;
a += angleDelta;
}
[CATransaction commit];}
http://img836.imageshack.us/img836/296/screenshot20111215at013.png
bringSubviewToFront did not work reliably on 5.0 (on 5.1 the hack was not needed)
I had to add a bigger transparrent UIButton around the button that behaved as if it was disabled to fix this on iOS prior to 5.1.
At last I've figured out that, even I send back views with CATransform3DMakeTranslation and layer.zPosition settings, touch events goes to views according to their frame position. The views that aren't currently even seen (overlayed by others) still catch touches. Writing just one line of code ([self.superview bringSubviewToFront:self]) for the view that is currently on screen solved the problem.
For testing this and understanding what I'm talking about, I've made simple test application that has only two buttons on it.
The blue and yellow buttons.The blue button overlays the yellow button so you can only see the blue one at the beginning.
On the touch up inside code for the blue button, I just send it back with buttons.layer.zPosition = -1. After this, there is no visible part of the blue button remains on screen, instead I see just the yellow button now, but when I touch the yellow button (or I think I am touching it) still blue buttons touch up inside code runs.
I'm not sure if this is the desired logic but it does not seem reasonable to me.
As I mentioned above, writing [blueButton.superview sendSubviewToBack:blueButton] while setting its layers zPosition to -1 works as expected.
I've built an app using the UITabBar template. I have a few tabbar items, one item displays a view. That view has a UIScrollView element that has paging enabled to mimic the behaviour of the iPhone springboard i.e. pages that can be scrolled left to right.
I'm trying to drop in a UIPageControl, so I've resize the UIScrollView so that it's slightly shorter than the parent UIView height and have placed a UIPageControl below it.
When I run the app the UIScrollView is always 100% of the height of the parent UIView and I can't see the UIPageControl.
I've got the following code in my viewDidLoad method of the view controller for the tab:
UIScrollView *tempScrollView=(UIScrollView *)self.view;
tempScrollView.contentSize=CGSizeMake(640,377);
This sets the content size ok and I can scroll left to right. I've tried adding:
tempScrollView.frame=CGRectMake(0, 0, 640, 377);
To to resize the scroll view but it still shows 100%. See diagram below showing the issue:
I think you shouldn't resize the frame to 640, 377 because it would make the paging stop working, once the contentSize would be the same as the frame size.
One solution would be to set the desired frame size in the interface builder (like the left most figure) and set proper autosizing masks. I gues what you are looking for is the configuration below
To check if the changes are working, I would use a uiscrollview of height visibly smaller, just to make sure the behaviour is the desired.
If you want your view to scroll you need to change the tempScrollView.contentSize to be bigger than tempScrollView.frame
If you do this:
CGFloat contentWidth = tempScrollView.frame.size.width*2;
tempScrollView.contentSize=CGSizeMake(contentWidth,377);
You will have 2 pages.
You need to activate paging too with:
[tempScrollView setPagingEnabled:TRUE];