I read all exists solution on stackoverflow for similar trouble but without lack.
Trouble in UITextView when i try scroll text to position with animation.
Top part of text disappear when scroll with animation, but if font size 15pt all is ok but if around 50pt then something goes wrong.
You can see it on video https://www.youtube.com/watch?v=EvIur672Q5k
I also try create my own method to animate scroll with loop and each loop move offset on 0.5pt it works but this utilised processor too much, and i cannot control animation time, because processor overloaded.
https://www.youtube.com/watch?v=Kw5hx3YAdMw
I also try create UITextView programmatically with same result.
I try split animation on parts with linear curve but it so ugly animation with shake.
- (IBAction) start{
_textView.scrollEnabled = NO;
_textView.scrollEnabled = YES;
UITextPosition *Pos2 = [_textView positionFromPosition: _textView.beginningOfDocument offset: 501];
UITextPosition *Pos1 = [_textView positionFromPosition: _textView.beginningOfDocument offset: 500];
UITextRange *range = [_textView textRangeFromPosition:Pos1 toPosition:Pos2];
CGRect result1 = [_textView firstRectForRange:(UITextRange *)range];
result1.origin.x=0;
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
_textView.contentOffset = result1.origin;
} completion:^(BOOL finished){
}];
}
I believe you're trying to do this
- (IBAction)start:(id)sender {
_textView.scrollEnabled = NO;
_textView.scrollEnabled = YES;
NSRange bottom = NSMakeRange(_textView.text.length, 0);
[UIView animateWithDuration:2.0 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
[_textView scrollRangeToVisible:bottom];
} completion:nil];
}
This should make a range of the text length and scroll to the bottom of it for you. If I have misunderstood your problem please let me know and I'll do my best to help
Related
I have a string like "Points (67)" that is displayed on a label.
Sometimes in my app, the points total can change, via an NSNotification.
So, perhaps it will change to "Points (117)". I don't want this to happen instantly, as the user's eye is likely to miss the change. I'd like them to notice.
I would like to just animate the 67 to 117 part. Possibly the size, maybe growing by 10% as it changes, then shrinking back down 10% to original size. Or perhaps the color. Preferably size, but I'm guessing that's not possible without creating additional labels.
Is this doable?
You cant animate the Font size ,But yes u can scale the UILabel through which you can achieve your goal.
Below are two ways through which you show changes in UILabel font sizes.
UIView Animation
[UIView transitionWithView:yourlabel duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
yourlabel.font = [UIFont fontWithName:#"HelveticaNeue" size:14.0];
}];
Scale Animation
CABasicAnimation*scaleAnimation[CABasicAnimationanimationWithKeyPath:#"transform.scale.xy"];
scaleAnimation.fromValue = #(1);
scaleAnimation.toValue = #00.5;
scaleAnimation.duration = self.animationDuration;
[yourlabel addAnimation:self.animationGroup forKey:#"pulse"];
You can do following animation to make user to notice the change:
[label setTransform:CGAffineTransformMakeScale(1.0, 1.0)];
[UIView animateWithDuration:0.3 animations:^
{
[label setTransform:CGAffineTransformMakeScale(1.5, 1.5)];
}
completion:^(BOOL finished)
{
if(finished)
{
[UIView animateWithDuration:0.15 animations:^
{
[label setTransform:CGAffineTransformMakeScale(1.0, 1.0)];
label.text = #"Points (117)";
}];
}
}];
You can change duration and scale as per your requirement....
Hope this will help you.
There is a button that horizontally shifts my table.
- (void)togglePreferencePageVisibility:(id)sender {
int translation = [self preferencesVisible] ? -PREFERENCE_TRANSLATION_HEIGHT : PREFERENCE_TRANSLATION_HEIGHT;
//animate tableview down
[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
_table.center = CGPointMake(_table.center.x, _table.center.y+translation);
}
completion:^(BOOL finished){
}];
}
When I call [_table reloadData], the table reverts to its original position. I tried manually readjusting the table position, like so
NSLog(#"before %#", NSStringFromCGRect(_table.frame));
[_table reloadData];
_table.frame = CGRectMake(initialTablePosition.x, initialTablePosition.y+PREFERENCE_TRANSLATION_HEIGHT, _table.frame.size.width, _table.frame.size.height);
NSLog(#"after %#", NSStringFromCGRect(_table.frame));
but no luck. Also the frame's have the same y position before and after.
You need to also adjust the auto layout constraints using the NSLayoutConstraint class. You can add, remove or change the values of NSLayoutConstraints. This is a VERY common question on stack overflow right now, due to the change from iOS 7 to iOS 8.
If you do not adjust the layout constraints then the view will be repositioned back to its original location. reloadData redraws the UITableView which causes the view hierarchy to reexamine its positions e.t.c.
As an example of making a view with a width constraint narrower:
CGRect frame = myView.frame;
frame.size.width -= 100;
//Next line now needed in iOS 8
myWidthConstraint.constant -= 100;
[UIView animateWithDuration:0.5 animations:^{
[myView setFrame:frame];
}];
EDIT: moving back example:
CGRect frame = myView.frame;
frame.size.width += 100;
//Next line now needed in iOS 8
myWidthConstraint.constant += 100;
[UIView animateWithDuration:0.5 animations:^{
[myView setFrame:frame];
}];
When using auto layout, you should not set any frames. If you do, when the view needs to redraw itself, the frame will be reset to the frame defined by its constraints. You should add an IBOutlet to a constraint between your table view and the top (or bottom what ever works for your use) of its superview (I'll call it topCon in the example below).
- (void)togglePreferencePageVisibility:(id)sender {
int translation = [self preferencesVisible] ? -PREFERENCE_TRANSLATION_HEIGHT : PREFERENCE_TRANSLATION_HEIGHT;
//animate tableview down
self.topCon.constant += translation; // this might need to be "-=" depending on whether your constraint is to the top or bottom
[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
[self.view layoutIfNeeded];
}
completion:^(BOOL finished){
}];
}
I'm using this block to animate a pulse on my text and when I do, the text moves to the right some and jerks back. Seems like it is due to some padding or something being added by interface builder.
[UIView animateWithDuration:0.5 animations:^{
// grow the label up to 130%, using a animation of 1/2s
myLabel.transform = CGAffineTransformMakeScale(1.3,1.3);
} completion:^(BOOL finished) {
// When the "grow" animation is completed, go back to size 100% using another animation of 1/2s
[UIView animateWithDuration:0.5 animations:^{
myLabel.transform = CGAffineTransformIdentity;
}];
}];
Reduce the anchorPoint by a factor of 1.3 on the way back. Change your code to this -
CGPoint anchorPoint = myLabel.layer.anchorPoint;
[UIView animateWithDuration:0.5 animations:^{
// grow the label up to 130%, using a animation of 1/2s
myLabel.transform = CGAffineTransformMakeScale(1.3,1.3);
} completion:^(BOOL finished) {
// When the "grow" animation is completed, go back to size 100% using another animation of 1/2s
myLabel.layer.anchorPoint = CGPointMake(anchorPoint.x/1.3, anchorPoint.y/1.3);
[UIView animateWithDuration:0.5 animations:^{
myLabel.transform = CGAffineTransformIdentity;
}];
}];
I tried your code. It is working fine for the labels which text is fitted in the label properly or those labels have the text alignment center.
So my suggestion is if you have label having static or fixed text then give the background color to label and check for label text if it is too large then make it as such so that text fit to label properly. Then your code will work fine.
Now if you have dynamic text then try to calculate the label width dynamically as below
UIFont *font = [UIFont systemFontOfSize:9.0];
CGSize stringSize;
stringSize = [myLabel.text sizeWithFont:font constrainedToSize:CGSizeMake(1000, myLabel.frame.size.height) lineBreakMode:UILineBreakModeWordWrap];
Then assign stringSize.width as mylabel width. Means here you will change the width of label dynamically.
Then you code will work fine as you want.
You should try this code i think it will help you,first it will Zoom your image to 130 % then it will zoom out your image to the original size
[UIView animateWithDuration:0.5 animations:^{
myLabel.transform = CGAffineTransformMakeScale(1.3,1.3);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 animations:^{
myLabel.transform = CGAffineTransformMakeScale(1,1);
myLabel.hidden=YES;
}];
}];
How do I control the speed of the scrolling text in a UITextView. I am new to iOS and can't figure this one out. Below is the method I am calling to start the scroll.
[InputTextField scrollRangeToVisible:NSMakeRange([InputTextField.text length]-1, -1)];
I want to be able to change the speed of the scroll.
Thanks
You can't change animation's speed of scrollRangeToVisible but you can use contentOffset
Be sure you using UITextView, this not work with UITextField
uint offset1=-1;
uint offset2=0;
UITextPosition *Pos2 = [_textView positionFromPosition: _textView.endOfDocument offset: offset2];
UITextPosition *Pos1 = [_textView positionFromPosition: _textView.endOfDocument offset: offset1];
UITextRange *range = [_textView textRangeFromPosition:Pos1 toPosition:Pos2];
CGRect result1 = [_textView firstRectForRange:(UITextRange *)range];
result1.origin.x=0;//reset x position to zero
[UIView animateWithDuration:3.0 delay:0.0 options:UIViewAnimationOptionCurveLinear
animations:^{
_textView.contentOffset = result1.origin;
}
completion:^(BOOL finished){
}];
I'm trying to animate a UITextField but I've been caught by a annoying and strange problem. My animation has the following sequence:
In first state the application has the UITextField, the camera UIButton and the cancel UIButton after the camera button that is not been showed because it is been positioned out of the limits of the application. Actually my application has 320 of width and the cancel button origin is (350,7)
In second state, when user touches on UITextField, the camera button alpha channel is set to 0 and the origin of cancel button is set to (247,7).
The final state is the same as first state after user touched on Return button of keyboard or in cancel button.
During process the UITextField width and the cancel button origin in x axis are animated.
My code is:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = NO;
CGFloat cancelButtonXOffset = CGRectGetMaxX(barcodeSearchButton.frame) - cancelButton.frame.size.width;
CGFloat searchFieldWidth = searchField.frame.size.width - cancelButton.frame.size.width + barcodeSearchButton.frame.size.width;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldWidth, searchField.frame.size.height);
cancelButton.alpha = 1.0;
cancelButton.frame = CGRectMake(cancelButtonXOffset, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 0.0;
}
completion:^(BOOL finished) {
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = YES;
}];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = NO;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldStartWidth, searchField.frame.size.height);
cancelButton.alpha = 0.0;
cancelButton.frame = CGRectMake(cancelButtonStartX, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 1.0;
}
completion:^(BOOL finished) {
barcodeSearchButton.userInteractionEnabled = YES;
cancelButton.userInteractionEnabled = NO;
}];
}
When the animation is executed until the final state ONLY for the first time, which means, user touched on UITextField, WROTE DOWN (this part is important) some text on field and after that the user touched on keyboard return button the problem appears. The problem is that the typed text in UITextField is animated when the width of UITextField is animated too.
The animation behaves like bellow:
The UITextField stretches back to its initial value.
Cancel button backs to its initial origin
Camera button is set to 1.0
The typed text flies from the top-left corner of UITextField and it lands into UITextfield to the position the it should not have gone.
The problem is that the step 4 should not happen and the problem is it happens only one time. If a start the process again (touch on uitextfield, type some text, touch on return key) the step 4 does not happen.
I spend a day long trying to solve this problem but I was unsuccessful.
Thanks for answers of everyone but I've found the solution some time ago. The correct way to start an animation in a UITextField, depending on the keyboard state, is overriding the methods textFieldShouldBeginEditing and textFieldShouldEndEditing.
My first attempt I was overriding textFieldDidBeginEditing and textFieldDidEndEditing to create the animations. I don't know the reason to the animations work in textFieldShouldBeginEditing and textFieldShouldEndEditing but not in textFieldDidBeginEditing and textFieldDidEndEditing. But it just works.
My revised code version:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
CGFloat cancelButtonXOffset = CGRectGetMaxX(barcodeSearchButton.frame) - cancelButton.frame.size.width;
CGFloat searchFieldWidth = searchField.frame.size.width - cancelButton.frame.size.width + barcodeSearchButton.frame.size.width;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldWidth, searchField.frame.size.height);
cancelButton.alpha = 1.0;
cancelButton.frame = CGRectMake(cancelButtonXOffset, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 0.0;
} completion:^(BOOL finished) {
searchField.clearButtonMode = UITextFieldViewModeAlways;
}];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldStartWidth, searchField.frame.size.height);
cancelButton.alpha = 0.0;
cancelButton.frame = CGRectMake(cancelButtonStartX, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 1.0;
} completion:^(BOOL finished) {
searchField.clearButtonMode = UITextFieldViewModeNever;
}];
return YES;
}
Set some placeholder text on the search field,
_searchField.text = #"placeholder"
and also set
_searchField.clearsOnBeginEditing = YES;
Or you can just clear out the value if it's equal to your placeholder text
on textDidBeginEditing
{edited to improve the fix}
I have this exact same problem, and some further details as well as a small hack that is indeed fixing it for me.
So first the further details:
The problem only occurs the first time the frame animation expands
the UITextField and there is entered text in the field. If the
UITextField is edited again, and the same animations happen again,
the problem does not happen.
searchField.clearsOnBeginEditing = YES; does not clear the problem.
I've been using placeholder text the entire time the problem has
been observed. It has no effect on the results.
Changing the text property for 1 frame does have the effect of clearing the problem.
Here is what I am doing to fix it:
In my viewDidLoad I am setting the text property to a single space, then dispatching once an assignment to an empty string.
-(void)viewDidLoad {
searchField.text = #" ";
dispatch_async(dispatch_get_main_queue(), ^{
searchField.text = #"";
});
}
Then in my methods that shrink and expand the UITextField, as well as move a cancel button on-screen, I check if this is an instantaneous animation and set the duration to 0.0f.
- (void)showCancelButton {
NSTimeInterval duration = 0.3f;
[UIView animateWithDuration:duration animations:^{
CGPoint buttonOrigin = cancelButton.frame.origin;
CGSize buttonSize = cancelButton.frame.size;
CGFloat buttonTravelDist = buttonSize.width + 10.0f;
CGPoint onscreenPos = CGPointMake(buttonOrigin.x - buttonTravelDist, buttonOrigin.y);
cancelButton.frame = CGRectMake(onscreenPos.x, onscreenPos.y, buttonSize.width, buttonSize.height);
CGPoint fieldOrigin = searchField.frame.origin;
CGSize fieldSize = searchField.frame.size;
searchField.frame = CGRectMake(fieldOrigin.x, fieldOrigin.y, fieldSize.width - buttonTravelDist, fieldSize.height);
}];
}
- (void)hideCancelButton {
NSTimeInterval duration = 0.3f;
[UIView animateWithDuration:duration animations:^{
CGPoint buttonOrigin = cancelButton.frame.origin;
CGSize buttonSize = cancelButton.frame.size;
CGFloat buttonTravelDist = buttonSize.width + 10.0f;
CGPoint onscreenPos = CGPointMake(buttonOrigin.x + buttonTravelDist, buttonOrigin.y);
cancelButton.frame = CGRectMake(onscreenPos.x, onscreenPos.y, buttonSize.width, buttonSize.height);
CGPoint fieldOrigin = searchField.frame.origin;
CGSize fieldSize = searchField.frame.size;
searchField.frame = CGRectMake(fieldOrigin.x, fieldOrigin.y, fieldSize.width + buttonTravelDist, fieldSize.height);
}];
}
This has completely fixed the situation for me.