I am placing array of images in a scrollview.
I need to autoscroll the scrollview. I am using the timer and increasing the position of scrollview.
My code looks like this.
- (void)autoscrollmethod {
Timer = [NSTimer scheduledTimerWithTimeInterval:7.5 target:self selector:#selector(moveRect) userInfo:nil repeats:YES];
}
- (void)moveRect {
NSLog(#">>>>>>>> %d",i);
[gallery scrollRectToVisible:CGRectMake(i,0,100,100) animated:NO];
if (i==(arraycount+1)*100) {
[gallery scrollRectToVisible:CGRectMake(0,0,100,100) animated:NO];
i=200;
}
else {
i=i+100;
}
}
It working fine,but I have a problem.
I am scrolling the view to position 800, but scrollRectToVisible:CGRectMake is at 600,then scrollview is not getting back to 600 position,and not autoscroll up to 800.
After 800 it will automatically scrolls normally.
How can I fix this?
Generally speaking, you should use the contentOffset property of the UIScrollView instead of manually using your own increment variable. Contentoffset changes depending on your scrolling and automatically changes itself.
Related
I am new in iOS developement.When I press the stopwatch start button I want to display the timer like counter token effect.I have attached image for your reference.I have done to display secs and minutes but I dont know, How animate autoscroll effect? How can I do this?
When the counter is moving it shouldn't jump from one number to another number, instead it should move from one number to next number smoothly, just like the petrol pump meter. Thanks
I have done something like this before - this code is not necessarily clean, but it does the job.
You want to create twoUILabels in your .h file:
IBOutlet UILabel *figureLabel1;
IBOutlet UILabel *figureLabel2;
Then you want to create a BOOL so that we can tell which UILabel is visible to the user.
BOOL firstLabel;
So lets imagine that the initial label (showing the number 1) is figureLabel1 and the future UILabel to be displayed (showing the number 2) is figureLabel2. However when the counter adds one, then the figureLabel2 moves up and takes the figureLabel1's place. Then, while the figureLabel1 is hidden, it takes the place of figureLabel2 when figureLabel1 was visible.
See here:
// Check what label is showing
if (firstLabel == YES) {
// Following code the hide and move the figureLabel1
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate: self]; //or some other object that has necessary method
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
// Slowing fade out the figureLabel1
[figureLabel1 setAlpha:0];
// Move the figureLabel1 up and out of the way
[figureLabel1 setFrame:CGRectMake(20, 108, 287, 55)];
[UIView commitAnimations];
// Following code the show and move the figureLabel2
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
// Slowing fade in the figureLabel2
[figureLabel2 setAlpha:1];
// Move the figureLabel2 up and into position
[figureLabel2 setFrame:CGRectMake(20, 141, 287, 55)];
[UIView commitAnimations];
// Update BOOL for next label
firstLabel = NO;
} else {
// Exactly the same but opposite
}
As I said, this is not pretty but it shows the basic concept. All the best!
You need to manually scroll tableView instead of scrollToRowAtIndexPath because this animation uses its own timer interval and its very difficult or we can say impossible to change its time interval.
So, I am Implementing an API for such kind of problems and made a demo app for you with smooth scrolling as you want.
You need to use an outer timer that fires every 1 second and an internal timer that will fire every 0.03 sec as my tableRow Height is 30 I calculated internal timer interval as :---
Move 30 pixels for 1 sec , then
Move 1 pixel for 0.33 sec inside internal timer.
The Internal timer will invalidate and fire every 1 second as initialized within outer timer.
And internal timer will perform the movement of cell.
dial4 is a tableView
Have a look at my code.
#define rowHeight 30
-(void)startCounter
{
outertimer=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(snapCell) userInfo:nil repeats:YES];
}
-(void)stopCounter
{
[outertimer invalidate];
}
-(void)snapCell
{
NSLog(#"Initialize Internal timer %i",secLsb);
secLsb++;
if (secLsb==10) {
[dial4 setContentOffset:CGPointMake(0, 0) animated:NO];
secLsb=0;
NSLog(#"dial content offset y is %f",dial4.contentOffset.y);
}
[internaltimer invalidate];
internaltimer=[NSTimer scheduledTimerWithTimeInterval:0.03
target:self
selector:#selector(automaticScroll)
userInfo:nil
repeats:YES];
}
-(void)automaticScroll
{
NSLog(#"val is & y ======== %f",dial4.contentOffset.y);
[dial4 setContentOffset:CGPointMake(dial4.contentOffset.x,dial4.contentOffset.y+1) animated:NO];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return rowHeight;
}
Have a look at Time Counter
From image it can be assume that you are trying to get an effect like count-down timer. Have a look at countdown timer here. It may helps you somehow.
Enjoy Programming !!
Refer both links for your output. It helps you
UIPickerView that looks like UIDatePicker but with seconds
and
How can I make my UIPickerView show labels after the selected value?
Thanks.
Several good ideas here so far, but I'll add another.
First, be sure to set the container view (your blue rectangle) to clip children, using the Clip Subviews checkbox in Interface Builder.
Second, add a set of child views with images of each numeral for each digit to be presented (4 * 10 = 40 child views in your case). Use tags in IB so you can easily access each one. Set the initial bounds to just below your bottom margin.
Call UIView animateWithDuration. In the animations block, set the new digit view's frame to appear in the clipped parent view's bounds, and set the old digit view's frame to just above the container's bounds. Since both view's frame changes are animated in the same block, this will create the effect of the new digit sliding up into place as the old digit slides out the top.
In the completion block, set the old digit's frame back to the original position below the container view.
With this approach, you can play with the duration and the timing curves, so that you cam emulate the pause that occurs with each digit fully displayed between transitions.
A similar approach can also be used with CALayer, or with sprites, but UIViews are lightweight, perform well, and easiest to assemble in Interface Builder.
I have an iPhone application with a UISlider. When my user presses the play button, I want my slider to move from a value of 1, slowly, to a value of 100. The slider slides for the duration of the recording that gets played back when my user presses the play button.
I looked at the UISlider documentation. The only method that seems like it might help me is the setValue:animated: method. However, when animated=yes, the slider moves to value 100 way too fast.
Any way to slow it down a little?
You can let the UIView animate itself rather than working out the tweening yourself, or writing callbacks. For Example, this animates the slider to it's maximum value from it's current value in 5 seconds. And it's a lot smoother than trying to do it yourself.
- (IBAction)play:(id)sender {
[sender setEnabled:NO];
[UIView animateWithDuration:5.0 animations:^{
self.slider.value = self.slider.maximumValue;
}];
}
If you don't believe me - here's a sample project that you can download to see it for yourself:
You should use scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: which is part of NSTimer to increment the slider more slowly. Increase the position of the slider on every tick. Something like this:
NSTimer *timerForSlider = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateSlider) userInfo:nil repeats:YES];
-(void)updateSlider {
[slider setValue:slider.value+1];
if(slider.value == MAXIMUM_VALUE) {
[timerForSlider invalidate];
}
}
I am using a UIToolbar in iOS and am trying to get a new button to 'arrive' by sliding in from the right. Is there a way to directly access the 'position' of the button on the bar? I currently have a messy workaround that is getting close to the desired effect, but i was hoping there was a way to move them using Core Animation, so i could implement the 'EaseInEaseOut' type timing functions. Any ideas?
- (void) testPart1 {
[NSTimer scheduledTimerWithTimeInterval:(0) target:self selector:#selector(testPart2:) userInfo:[NSNumber numberWithInt:500] repeats:NO];
}
- (void) testPart2:(NSTimer*)sender {
int countdown = [sender.userInfo integerValue];
theSpace.width = 10+(int)countdown;
itemTestButton.width = 49;
itemTestButton.width = 50;
countdown -= 5;
if(countdown>0)
[NSTimer scheduledTimerWithTimeInterval:(0.004) target:self selector:#selector(testPart2:) userInfo:[NSNumber numberWithInt:countdown] repeats:NO];
}
The premise here was using an NSTimer to change the width of a Fixed Space Bar Button item, and count down to zero. I found I had to change the width of an actual button to make it work, otherwise no 'animation' would occur. It's messy I know, someone must have a cleaner way.
I would suggest adding a plain UIView as a subview of the UIToolbar that is rendered exactly as the bar button would be (you could get this by calling renderInContext: on an existing button) and then animate that view into the proper position. In the completion block of that animation you could then set the real button and removeFromSuperview the animation view, and it will look indistinguishable to the user.
I have one scrollview ,on that I am using imageview. I have horizontal scrollview size of 320 width and 40 pixel height.
I have number of images on scrollview.
I want when image comes center of scrollview,the size of image should increases by 40% in scale.
Your imageviews would be better considered as in the scrollview not on it. So you could make the scrollview as high as the scaled up size of the images. You will I imagine place the images central vertically. Your scrollview would be in a viewcontroller that is the scrollviews delegate. The viewcontroller could then check the scrollviews offset to determine which image is in the centre and make sure it is scaled up, and make sure all other images are scaled down.
Your next problem would be looping the scrollview
implement timer in viewDidLoad:
NSTimer *t;
[t scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(timerFired1:) userInfo:nil repeats:YES];
create a callback for timer:
- (void)timerFired1:(NSTimer *)timer {
if (clubScrollView.contentOffset.y + clubScrollView.frame.size.heigth/2 == yourImage.frame.center)
[UIView animateWithDuration:1
animations:^{
[YourImage setFrame:CGRectMake(x, y, width, height)]; //set any frame
}];
}
invalidate timer in viewWillDisappear:
[t invalidate];
I have a UITextView that has a lot of content (e.g. credit view), and I want to create an automatic scrolling view for it (something like the credits page for Firefox)
where it automatically scrolls the names
I have tried the following, but it is not smooth, and I also require it to happen automatically when user goes to that view
CGPoint scrollPoint = textView.contentOffset;
scrollPoint.y= scrollPoint.y+10;
[textView setContentOffset:scrollPoint animated:YES];
Any guidance?
Since UITextView is a subclass of UIScrollView, you can use its scrollRectToVisible:animated: method to scroll with animation to any point you wish.
The PageControl sample code demonstrates its use (although it's scrolling horizontally).
So far I have done this, but still it is not smooth...
Any suggestions?
- (void)viewDidLoad {
[super viewDidLoad];
[self run];
}
-(void)run{
CGRect Frame1 = CGRectMake(5.0,5.0, 100.0,400.0);
CGPoint scrollPoint = textView.contentOffset;
scrollPoint.y= scrollPoint.y+100;
[textView setContentOffset:scrollPoint animated:YES];
[textView scrollRectToVisible:Frame1 animated:YES];
NSTimer *time;
time=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(run) userInfo:nil repeats:YES];
}
Neither scrollRectToVisible: animated: nor setContentOffset: animated: have a property to control the speed or duration in which the animation occurs, so both will scroll fairly quickly to the destination point. They aren't good solutions for something like credits, which should scroll slowly.
Using UIView animateWithDuration: and then passing a contentOffset in the animation block is probably the best way to do this. However, there is a bug that clips text at the top if the length of the text is too long (even in iOS 10.0 SDK). There are two viable work-arounds for this bug discussed here:
UIView.animateWithDuration on UITextfield's contentoffset: It clips the text (Swift)