Xcode - content offset in scroller view - scrollview

I have a bug I've been looking at for over two hours and still don't know why it happens.
I have a registration form on a scroller view, which scrolls down if they keyboard is in the way of the textfield (function called at Editing Did Start).
Here's the code segment where the bug happens:
CGPoint scrollerOffset = scroller.contentOffset;
UITextField *currentTextField = sender;
CGPoint textFieldOrigin = currentTextField.frame.origin;
if (scrollerOffset.y < textFieldOrigin.y) {
scrollerOffset.y = textFieldOrigin.y - currentTextField.frame.size.height;
NSLog(#"Offset: %f",scrollerOffset.y);
[scroller setContentOffset:scrollerOffset animated:YES];
}
Now here's where the fun starts.
If I have the simulator like this and click inside the Phone Nr field, NSLog shows 590.000 for scrollerOffset.y and the text field jumps all the way to the top of the scrollview, as it should, just as the image next to it shows.
BUT if I have the simulator like this and click inside the Phone Nr field, NSLog shows 590.000 again but the scrollview doesn't jump up to show the text field...
Edit: If I don't animate the scrolling, it works perfectly, only bugs out when it's animated.

Well I've found the solution after a day of thinking, so if anyone has the same problem, heres's the solution:
Solution from here: http://www.pressingquestion.com/1128098/Disable-Uiscrollview-Scrolling-When-Uitextfield-Becomes-First-Responder
Basically, iOS has an in-built scroller, which is also scrolling for you if the text field is off the screen (usually the center of the text field is off the screen, off the screen being out of view, if it's hidden by the keyboard, it's still considered to be on the screen). So I called my function, did the scrolling, then iOS did his scrolling and messed me up. So you need to disable iOS' in-built scrolling.

Related

Resize views when menubar autohides/appear in fullscreen mode

I'm working on an OSX app that supports a fullscreen mode.
The window is generated from a nib file but everything else is handled programmatically.
When I goes in fullscreen mode, my views resize properly but when the menu bar appear/disappear, setFrame don't get called for either the contentView or my own views. I'd to be notified
Is there a delegate to implement to catch those notifications? Or do I have to subclass NSWindow and find out how Safari handles its menu bar by reversing it?
It would be helpful to see some code, how exactly "your views resize properly".
But next info might help:
When a window goes fullscreen it occupies entire screen after the end of the fullscreen animation. The main menu bar shows over the window ("above" in sense of z-ordering). So when main menu bar shows/hides frame of your window and content view don't change.
Also note, that -[NSScreen visibleFrame] returns unoccupied frame. And it will not return whole screen frame until the end of the fullscreen animation.
After some researches, I could at least get ride of the dirty gray bar at the top of the screen by subclassing the window's content view and add the following code to the setFrame method, before call super:
//isFullscreen
if(([self.window styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask)
{
frameRect.size.height = self.window.frame.size.height;
frameRect.size.width = self.window.frame.size.width;
}
The window get resized to the screen size before setFrame get called, so we can use its size to update frameRect to window's size.

backBarButtonItem with popViewController and swipe

My App logic is like that: VCA => VCB, and there is a scroll view in VCB with swipe left and right function. Some code help to understand structure, in VCB:
self.scrollView.pagingEnabled = YES;
self.scrollView.directionalLockEnabled = YES;
self.scrollView.contentSize =CGSizeMake(CGRectGetWidth(self.scrollView.frame) * numberPages, CGRectGetHeight(self.scrollView.frame));
so what I want is list some pages horizontally and swipe to left and right to navigate. Each page has it own view controller(child view controller of VCB) and I add them like that:
if (controller.view.superview == nil)
{
[self addChildViewController:controller];
[self.scrollView addSubview:controller.view];
[controller didMoveToParentViewController:self];
}
So far it works fine for iOS 6. I can swipe to change page. All function inside each page also works fine.
Then the problem comes with iOS 7's new feature, swipe to right to automatically call popViewControllerAnimated:, same effect like click go back button. To solve the conflict, I disable the interactivePopGestureRecognizer: self.navigationController.interactivePopGestureRecognizer.enabled = NO;
and it works ok, no force to pop back when I just want to swipe change the page.
Now the real problem. I set a back button(backBarButtonItem) on navigation bar. Every time I use that button pop from VCB back to VCA and current page is not the first page (that means there is at least one page on the left side), the pop animation is like first change page to the left side one, then immediately show VCA without any animation.
So any solution? Please help me.
First of all, it is hard to determine the problem without any piece of your code.
And secondly, why won't you create the button yourself, and add a target to it, a function that'll dismiss / pop the view controller?

How to control nested scrollviews

In my iphone application I want to use 2 scrollviews and they have some images inside. Well, my question is when I scroll vertically on my first scrollview I want to explore the content of it however when I scroll horizontally I want to move to my second scrollview. I hope I explained clearly.
Well, I tried to use 3 scrollviews first of them located on the background, others are located on the first scrollview but I can only control the background scrollview or the others at once.
Is there a way to control first one horizontally and the others vertically.sorry for my english, hope it makes sense.
I have two recommendations.
1) Scrollviews can scroll horizontally and vertically - so you dont need two of them if you have content in a vertical direction and content in a horizontal direction. You can use one.
2) If for some reason you really do need 2, then you can detect a horizontal swipe by subclassing UIScrollView and switch to the other.
Remember that a UIScrollView will scroll in any direction that exceeds its contentSize. So all you need to do in the first case (1) is take the view that is inside say scrollview 2 (the horizontal scrollview) and put that view in the scroll view to the left or the right outside of the scrollviews viewport when the user scrolls they will see that view and can of course scroll vertically there as well.
If you use method 2 - make sure that the content size of scrollview one is at leat a few pixels more wide than the content size so that you can detect a horizontal swipe then invoke the coe to switch to your other scroll view. If you dont subclass UIScrollview to get the swipe you probably wont get the event. So do that add a little to the width of that view and then look for a value less than the left edge of the scroll view and switch to the other scroll view. You can do the same in reverse to go back to the previous scrollview.
I hope this helps - sorry no code at the moment, but I do have code working on iOS and OSX that does this.
You can distinguish both UIScrollView via if statement
Set delegate of both UIScrollView
Then compare your scrollView in its delegate method. You can change your delegate method according to your requirement -
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(firstScrollView == scrollView)
{
//Do your work for firstScrollView
}
if(secondScrollView == scrollView)
{
//Do your work for secondScrollView
}
}
try to do in delegates methords
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
set some conditions like
if(myScroll1)
{
//scroll vatical.
}
if(myScroll2)
{
//scroll horizontal.
}
this is not complete code this is an idea Best of luck..

How to position progress spinner inside the title bar of a Mac application

I am trying to place a progress spinner at the right side of the the title bar of the window of my Mac OS X application, but I can't do that with the Interface Builder, as it doesn't let me drag the view inside it.
So, I tried to put it in the title bar programmatically, with the following code inside the applicationDidFinishLaunching method in AppDelegate.m:
loadingSpinner = [[NSProgressIndicator alloc] init];
[loadingSpinner setFrame:NSMakeRect(485, 0, 17, 17)];
[loadingSpinner setStyle:NSProgressIndicatorSpinningStyle];
NSView *titleBarView = [[_window standardWindowButton:NSWindowCloseButton] superview];
[titleBarView addSubview:loadingSpinner];
However, this is putting my progress spinner view at the bottom of the window instead of the title bar. It appears NSMakeRect() is positioning it relative to the bottom of the window, not the top.
If I change the second parameter of NSMakeRect (y position) to something like 370, it puts the loading spinner in the place I want it to be, but obviously when I resize the window vertically, it brings the progress spinner together to the bottom.
I've never seen something like this before. How can I fix that?
P.S.: Also, I don't know if there's a "more right" way to get the title bar view. As you can see, I'm using the superview of the close button view to get it, which seems a bit "dirty".
Randall Brown has some code to put a button in an NSWindow's title bar on his blog. You were on the right track. The superview of the close button is the entire window including the title bar. Its a little less hacky to get it with [[_window contentView] superview].

Resizable UILabel which scrolls across the screen

Right, I'm trying to get a label with text in it (done already obviously), which scrolls across the screen.
The text that is input into the label is done by a UITextField and a UIButton. This updates fine.
But I'm trying to get the UILabel to resize accordingly to the amount of text input, so that the WHOLE lot of text scrolls across the screen.
This is the code I have at the moment for the scrolling label:
[lblMessage setText: txtEnter.text];
CABasicAnimation *scrollText;
scrollText=[CABasicAnimation animationWithKeyPath:#"position.x"];
scrollText.duration = 3.0;
scrollText.repeatCount = 10000;
scrollText.autoreverses = NO;
scrollText.fromValue = [NSNumber numberWithFloat:500];
scrollText.toValue = [NSNumber numberWithFloat:-120.0];
[[lblMessage layer] addAnimation:scrollText forKey:#"scrollTextKey"];
The problem is, sometimes is starts scrolling in the middle of the screen, and sometimes vanishes before it has fully gone acrosss.
It also cuts of text due to the label being one size.. I don't know how to change this.
Thanks in advance.
Dom
I believe something similar to the solution for this question would work for this case.
You could embed the UILabel in a UIScrollView, with the UIScrollView set to the max size of the label that you want to display on the screen at one time. The UIScrollView would need to have its scroll indicators turned off using its showsHorizontalScrollIndicator and showsVerticalScrollIndicator properties. On a change of text, you could do the following:
[lblMessage setText: txtEnter.text];
[lblMessage sizeToFit];
scrollView.contentSize = lblMessage.frame.size;
followed by the panning animation code as described in the above-linked question, with the frame to be panned to being the far right of the UILabel. This would cause the text to scroll at a constant rate across the label. If you want the label to scroll back to the beginning, you could use the UIView setAnimationRepeatAutoreverses: and setAnimationRepeatCount: methods in the beginning of your animation block.
The label resize worked great thanks!
Now, i've put the label into the scrollview and i've got that showing up.. but I'm now not sure of the exact animations to add to that. I tried some of the ones on the link you gave me, but they're not working.
EDIT: Nevermind, I've got it all working now.
CGPointMake(x, x) is what i needed for the contentOffset.