NSScrollView scroll bar draws on top of all views - objective-c

I have two overlapping views.
An NSTableView (the list of songs), I'll call it the table view
A layer backed NSView (for the play controls at the bottom), I'll call it the play controls view
I was using layer backed views to render the table view previously and this caused the scroll bar to render behind the play controls view, great! But as I loaded up the table view with 150+ rows of data the app slows down pretty bad as I scroll.
I changed setWantsLayer: to NO and now the table view is much snappier, great! But now the scroll bar seems to render on top of the play controls view.
Good:
Bad:
Any ideas whats going on here? (I'm a core animation rookie if you can't tell)

Why don't you resize the entire scrollview and put the play controls view below the list? It seems by your sceenshot that the play controls view is a subview of the scrollview. Is this necessary?

Resizing the entire scrollVIew could be a solution, but you might as well set the scrollIndicatorInsets:
yourTableView.scrollIndicatorInsets = NSEdgeInsetsMake(0, 0, bottomValue, 0);
Here bottomValue would be something like 50 -150, depending on the height of your view, you might have to test this, but this will do the trick.
Edit: I just see you are working on OSX, my solution works on iOS, i hope the NSEdgeInsetsMake works on Max OSX similar to UIEdgeInsetsMake does on iOS.

Related

Objective C Tap Gesture no working after frame resize

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.

Mechanisms to move a view partly offscreen

I have a problem that nobody has yet offered any help with so let me ask a technical question to help me diagnose it on my own.
What mechanisms does the system have for moving a view so it appears to be partly off screen besides changing the view's frame (i.e. bounds/center) or transform?
This is an app which needs to run on iOS 5/6 still so I'm not using auto layout.
I have a fullscreen view reached via a push segue.
After a pause I hide the (translucent) status and navigation bars.
When the bars hide with animation they slide up off the screen.
In iOS 5/6 this just exposes the top of the view (which is an image). In iOS 7 it moves the entire view up "offscreen" a corresponding amount (i.e. 64 points if I hide both bars) showing a bar of content "below" the view at the bottom of the screen.
When I un-hide the bars (via a tap) the bars appear and the view moves back down to occupy the whole screen.
Whether the VC is set to extend the view under bars or not doesn't affect the behavior.
I have not been able to reproduce this behavior in a simplified app.
In either state, i.e. partly offscreen or fully onscreen, the top-level view frame remains {0, 0} 320 x 480 and the transform matrix remains {1, 0, 0, 1, 0, 0}. I have no idea what property of what object the system is changing to visually move the view. Perhaps if I knew what object/properties to examine I could deduce something about what is going on. Can anybody tell me how the system might be doing this?
The answer is that the "view" that was being moved was being presented by a UIPageViewController and I wasn't thinking about that. The UIPageViewController is presenting the child views inside a UIScrollView (subclass, I think) and so the scroll insets for the containing UIScrollView were being changed by iOS 7. Since the whole "presenting as a child" thing actually works -- of course I couldn't see the problem in the child view.
The "fix" was to un-check the View Controller setting for Adjust Scroll View Insets for the UIPageViewController view.

How to draw in code an imageview

I have a problem. I want for each record in my core data database to draw an UIImage view on screen. But the problem is that I want to make a sort of grid. On the link below you see what I want to achieve.
picture
So my question is, how do I draw an image on screen in code. And place those images in a sort of a grid. using a collection view is no option, because the app should be running on all IOS devices.
While you could implement a custom UIView and implement the drawRect: method and draw UIImages there, I suggest just using multiple UIImageViews as subviews on your "main" view. Your view might be embedded in a UIScrollView, or you could use a UITableView with custom UITableViewCells. Whichever is easier is probably related to how you can interact with the view.
Building that one huge image view is something that I'd definitely try to avoid - it costs many many (probably unnecessary) memory, and it might be slow as well. Definitely not very flexible to handle, and a pain to update dynamically.
A quick cheat for something like this is to use a Table View and then in each cell to place another TableView but rotated at 90 degrees.
You can then use this second TableView to display the pictures etc...
This will give you a table that scrolls up and down and then each cell can scroll left to right.
I'd suggest subclassing UITableViewCell and setting it up as a UITableViewDelegate and UITableViewDatasource.
You will also have to remember to rotate the content of these "sub"tables by 90 degrees also so that they are the right way up.
This sounds like a lot of work but if you push the management of the sub Tables into the cells then it actually becomes quite easy.

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!