I saw this effect today where the navigation bar title seemingly starts within the view, then shrinks and moves upwards into the navigation bar's title as you scroll the page, it then reverses to its original state when scrolled back to the top.
Does anyone have any insight on how this is done? Is a navigation bar used at all, or is it being mocked using a UIView that shrinks in height and the background colour darkens? Perhaps the title is a label converted to a UIImage and scaled down rather than the font size decreasing?
Just speculating on possible techniques.
Would love to get some opinions on this. Thanks in advance.
Yes, You can change the size of the font and the origin of the Navigation Bar in accordance with your gesture recognizer.
navigationBar.frame.origin.y = -10
will shift the Navigation bar up by 10 points. The font can be changed using
if let font = UIFont(name: "Lato-Light.ttf", size: 34) {
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName: font]
}
This format is because using a forced unwrap ! will crash the app with UIFont
In this context, font can be a variable where you call the normal init with same typeface and different size.
These two operations should be performed whenever the gesture recognizer updates its value or scroll position. You may or may not have to redraw the view, however.
Related
Context
I have an NSSplitView in my app that has 3 panes. I've subclassed NSSplitView and it has a single override:
-(CGFloat) dividerThickness { return 1.0f; }
I have disabled ALL the delegate methods that constrain divider min/max points and resize subviews, etc.
The Problem
When I drag any divider on a retina screen, the divider's thickness fluctuates during the drag. See this video: http://incident57.com/divider.mp4
This happens no matter what divider thickness I use---the thickness always varies by about 1px during drag.
This DOES NOT HAPPEN on non-retina screens. It also DOES NOT HAPPEN when the window itself is resized. The divider width only fluctuates when the divider itself is dragged.
(If you look really closely, you can see that there's some blank, white space between the views where it looks like NSSplitView should be drawing the divider, but isn't. Look at the end of the brown selected table row in the video.)
What I Need
How do I fix this so that the divider width stays constant during drags on retina screens?
I solved this problem by implementing this NSSplitViewDelegate method:
- (CGFloat) splitView:(NSSplitView *)splitView constrainSplitPosition:(CGFloat)proposedPosition ofSubviewAt:(NSInteger)dividerIndex
{
return floor(proposedPosition);
}
It's also worth pointing out that this issue only manifests if the subviews within the panes of the NSSplitView are NSScrollViews. Normal NSViews inside the panes will not cause the divider-width fluctuation.
Layer-backing the split view (i.e. [splitView setWantsLayer:YES]) should also fix this.
Since scroll views will often auto-layerback themselves, their layer overlaps the drawn split view divider when non point aligned.
I'm currently working on my very first app and I've changed the size of the UINavigationBar and UITabBar and now I have extra space black space in the general viewing area (etc. ViewController, DetailViewController). How can I change the viewing area to accommodate for this new size?
I've pasted how I'm currently setting the new size for both UINavigationBar and the UITabBar.
/* Get the screenarea of the device */
CGRect screenArea = [[UIScreen mainScreen] applicationFrame];
/* Define the size of the navigation bar */
CGRect viewHeaderbBarFrame = navigationBar.frame;
viewHeaderbBarFrame.origin.y = screenArea.origin.y;
viewHeaderbBarFrame.origin.x = screenArea.origin.x;
viewHeaderbBarFrame.size.height = 44;
viewHeaderbBarFrame.size.width = screenArea.size.width;
navigationBar.frame = viewHeaderbBarFrame;
/* Define the size of the footer bar */
CGRect viewTabBarFrame = tabBar.frame;
viewTabBarFrame.origin.y = screenArea.size.height - 26;
viewTabBarFrame.origin.x = screenArea.origin.x;
viewTabBarFrame.size.height = 46;
viewTabBarFrame.size.width = screenArea.size.width;
tabBar.frame = viewTabBarFrame;
Thanks.
basically by shrinking your tabbar and navbar, you need your view to expand. I'm assuming that you are using a tabbar for primary navigation.
Figure out the proper size and adjust your view like this:
[[self.tabBarController.view.subviews objectAtIndex:0] setFrame:CGRectMake(newX,newY,newWidth,newHeight)];
in the buyer beware category, if your goal is the app store, you would be wise to review the guidelines on modifying those elements. I'm not sure of all the specific points, but I think apple frowns making changes like that to plainly displayed core navigation elements.
Also, this approach works well for the current screen dimensions, but may not work if the rumors are true and the next phone has a bigger screen.
be well.
You should never have to mess with the view height in this way. Views are pushed onto the nav bar. Their size should be set to fit a 320 x 480 screen minus tab, nav, and title bars. And you should set the AutoResize width/height as flexible and the left/rigth/top/bottom to not-flexible (just leave them out).
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
iOS likes everything to to be spring loaded and pinned to one another. Then when you rotate things, it all sticks and moves properly. They do all the work for you. So, it's best to embrace their funky way of handing things. The interface builder gui can help. It even lets you test out rotation if you want. And you can set the option of tab/nav/title bars too. Or if you understand it, then you can also do this manually.
At the moment I have an UIImageView inside a window. When the scene loads I save its position with:
imageView.center
The user can drag it around. On some occasions the item gets animated back to its original position which has been saved. This all works fine, when I hold the IPad vertically.
When I hold it horizontally though I cant move it back to that position, because in landscape mode I cant use the position which was saved in vertical orientation mode. this is because in Interface Builder I set the item to get auto sized relative to the borders (meaning if the item was in the center, then rotating the IPad it still stays in center)
So my question is: How can I get the correct original position the item would have in landscape orientation?
I tried to calculate the position by hand like this:
- (CGPoint)getHorizontalCoordinatesForPoint:(CGPoint)point
{
CGSize size = [[UIScreen mainScreen]applicationFrame].size;
CGFloat relativeX = (point.x / (size.width));
CGFloat relativeY = point.y / (size.height);
CGFloat horizontalScreenX = relativeX * (size.height);
CGFloat horizontalScreenY = relativeY * (size.width);
return CGPointMake(horizontalScreenX, horizontalScreenY);
}
but this position is a bit off. I think it is because I dont take into account the size of the navigation bar. Is there some converting function in ios which already does what I want?
Don't.
Rather, instead of saving [imageView center] when the scene loads, save it at key points:
-touchesBegan:withEvent: (or, if you are using gesture recognizers, in the gesture recognizer callback).
-didRotateFromInterfaceOrientation:
The minor complication is what happens if a user, say, is working in landscape, quits the app, rotates the portrait, and relaunches the app. In this case I would start the app in landscape and let the autorotation to portrait kick in and correct your center point.
I need help. I have an app like Adium with vertical sliders. But my app change the window height, depending on content. In case if the Screen height less than my app'a window height my window reduces the height automatically.
When I'm trying to use setFrame to my window and set window.frame.size.height higher than screen height then nothing happens.
So the question is: how to set window frame higher than screen height?
By default, the frameworks make sure you cannot resize your window to be outside the screen frame. To change this behavior, subclass your NSWindow, and override the constrainFrameRect:toScreen: method to return the unaltered frame; something like this:
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
{
//return the unaltered frame, or do some other interesting things
return frameRect;
}
I have a button that sits on top of an NSScrollView, not within. When the scrollview scrolls, the button get's clipped with part of the button going along with the scrolling and the other part staying positioned.
To better describe the issue here's a video of the issue:
http://dl.dropbox.com/u/170068/ScrollTest.mov
The planned goal was to have a button sit in the top right corner of a text view but stay there when the text view scrolls. So if anyone has any thoughts on how to achieve this it would be greatly appreciated.
You should subclass NSScrollView and override "tile" method to position sub-controls of the scroll view.
- (void)tile
{
[super tile];
if (subControl)
{
NSRect subControlFrame = [subControl frame];
// adjust control position here in the scrollview coordinate space
// move controls
[subControl setFrame:subControlFrame];
}
}
I have used this way to implement a custom ScrollView with zoom control and background color selector embedded.
Overlapping views isn't recommended for non-layer-backed views. I think Interface Builder will even warn you about this. The easiest way to work around this would be to make your button layer-backed.