Creating randomly generated horizontal flying labels - ios

I would like to add a feature to my app that involves labels with different keywords flying horizontally across the view. Ideally, I would like this to be done with an array of words, that are randomly selected to fly across the screen at different velocities and in 3-4 different positions (vertically) on the screen.
I have been doing some research, and maybe I am searching for the wrong thing, but I can't find much advice to get an idea of where I should start. I am only able to find how to move sprites to random areas of a view.
I would like to have more to show, but unfortunately the only code I have so far is as follows:
func generateWords() {
let keyWordArray = ["Word 1", "Word 2", "Word 3", "Word 4", "Word 5"]
for _ in 1...5 {
let randomIndexWords = Int(arc4random_uniform(UInt32(keyWordArray.count)))
}
}
How can I randomly generate multiple labels, at different vertical positions, that fly at different speeds across the screen and then disappear? This would need to happen infinitely until the view is closed by the user.
Thanks!

You want to first get the screen height:
CGFloat height;
height = [[UIScreen mainScreen] bounds].size.height;
You can then decide on the vertical position yourself i.e if you have ten labels divide the height by ten then increment up. To animate the labels you need to place the frame off the screen on one side and then place it on the opposite side. You can animate a UIView, in this example the initial label frame is (someXOffTheScreenOnTheRight, someY, widthOfLabel, HeightOfLabel) :
[UIView animateWithDuration:0.8 delay:0 options:0 animations:^{
[self.view addSubview:label];
label.frame=CGRectMake(-10, someY, widthOfLabel, heightOfLabel);
} completion:^(BOOL finished){
[label removeFromSuperview];
}];
This will animate the label from right to left. You can tweak the speed by changing the duration.
Of course if you want to use random Y coords then use the arc4random method.
That should be enough to get you going..

Related

Zoom Effect on Paging UIScrollView?

I'd like to implement a "zoom" effect on a paging UIScrollView that I've created, but I am having a lot of difficulty. My goal is that as a user begins to scroll to the next page, the current page zooms out to become a little bit smaller. As the next page comes into view, it zooms in until it becomes its full size. The closest thing I could find to an example was this...
https://www.pinterest.com/pin/147141112804210631/
Can anyone give me some pointers on how to accomplish this? I've been banging my head against a wall for the last 3 days on this.
I would recommend using the scrollView.contentOffset.y of your paginated UIScrollView to keep track of the scroll and to use that value to animate the transform of your views inside the UIScrollView.
So add your paginated scrollview and make self as delegate.
paginatedScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [[self view] bounds].size.width, [[self view] bounds].size.height-paginatedScrollViewYOffset)];
[self.view addSubview:paginatedScrollView];
paginatedScrollView.pagingEnabled = YES;
[paginatedScrollView setShowsVerticalScrollIndicator:NO];
[paginatedScrollView setShowsHorizontalScrollIndicator:NO];
[paginatedScrollView setAlwaysBounceHorizontal:NO];
[paginatedScrollView setAlwaysBounceVertical:YES];
paginatedScrollView.backgroundColor = [UIColor clearColor];
paginatedScrollView.contentSize = CGSizeMake([[self view] bounds].size.width, [[self view] bounds].size.height*2); //this must be the appropriate size depending of the number of pages you want to scroll
paginatedScrollView.delegate = self;
Then use the delegate method scrollViewDidScroll to keep track of the scrollView.contentOffset.y
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"Scroll Content Offset Y: %f",scrollView.contentOffset.y);
//use here scrollView.contentOffset.y as multiplier with view.transform = CGAffineTransformMakeScale(0,0) or with view.frame to animate the zoom effect
}
Use this Code scrollview its zoom in when scroll next page, the code is given below,
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
GridCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CollectCell" forIndexPath:indexPath];
cell.myscrollview.minimumZoomScale = 5.0;
cell.myscrollview.zoomScale = 5.0;
cell.myscrollview.contentSize = cell.contentView.bounds.size;
return cell;
}
if you change the zoom scale value its automatically zoom in or zoom out to be showed when scroll next or previous page.
hope its helpful.
I actually just posted an answer to a very similar question, where somebody tried to achieve this effect using a UICollectionView. The link to my answer is here: https://stackoverflow.com/a/36710965/3723434
Relevant piece of code I will post here:
So another approach would be to to set a CGAffineTransformMakeScale( , ) in the UIScrollViewDidScroll where you dynamically update the pages' size based on their distance from the center of the screen.
For every page, calculate the distance of its center to the center of yourScrollView
The center of yourScrollView can be found using this nifty method: CGPoint point = [self.view convertPoint:yourScrollView.center toView:*yourScrollView];
Now set up a rule, that if the page's center is further than x away, the size of the page is for example the 'normal size', call it 1. and the closer it gets to the center, the closer it gets to twice the normal size, 2.
then you can use the following if/else idea:
if (distance > x) {
page.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
} else if (distance <= x) {
float scale = MIN(distance/x) * 2.0f;
page.transform = CGAffineTransformMakeScale(scale, scale);
}
What happens is that the page's size will exactly follow your touch. Let me know if you have any more questions as I'm writing most of this out of the top of my head).
I've done some work on stylized app guide page before.
For Me, I would use CADisplayLink to track the contentOffset.x of the scrollView, associate the value with your animation process. Don't put your views on the scrollView, put them on an overlay view of this scrollView.
This solution follows the philosophy: Fake it before you make it.
Based on CADisplayLink and physics simulation of UIScrollView, you will get smooth animation. Believe me.
What you really want isn't a UIScrollView, it's a UICollectionView with a custom layout. UICollectionViewLayoutAttributes has a transform property that you can set.
Say for example, in layoutAttributesForElementsInRect::
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let attributes = super.layoutAttributesForElementsInRect(rect) else {
return nil
}
return attributes.map { attribute -> UICollectionViewLayoutAttributes in
if attribute.frame.origin.y < 0 {
let scale = -attribute.frame.origin.y / attribute.frame.height
attribute.transform = CGAffineTransformMakeScale(scale, scale)
}
return attribute
}
}
Here, you're filtering by if the element is on the screen (so non-visible elements won't be counted) and checking to see if the y offset is less than 0. If it is, you take the difference between the negated y value and the item's height and turn that into a proportional scale.
You can do it however you want, if you want the scale to be between 1 and 0.5 for example. I like this way of doing things over mucking around with a scroll view.

Animate Change Height and Width at Different Times

I have an image that I am animating in order to make it look as if it is "breathing".
Currently I have the image moving in a decent manner with the following code below: (I am animating a UIView that contains a few UIImageView's, which all move as one)
- (IBAction)animateButton:(id)sender {
[UIView animateWithDuration:0.64
delay:0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
_testView.transform = CGAffineTransformMakeScale(1.08f, 1.02f);
} completion:nil];
}
HOWEVER, I can not seem to figure out how to animate stretching the image in the x at a different rate as the y. The point of this is to appear as if the image is actually alive without appearing to cycle through a clear repetitive motion.
I tried by attempting to anchor the center of the UIView to a specific location, then add some number to the width, through an animation of lets say 1.0 seconds.
I then tried to simultaneously call another animation that does the same animation only to the height, with a different amount added, for about 1.3 seconds. I could not get these two to perform at the same time though, as one would take precedence over the other.
If someone could lead me in the right direction as to animating a repetitive stretch of the width and height at different rates I would be most appreciative. Thanks!
Consider that two changes overlapping in time look like this:
|---- change x ---|
|---- change y ----|
If the two intervals are arbitrary and overlapping, the can be represented by three animations: one changing one dimension individually, one changing both dimensions together, and another changing one dimension individually.
You can see that there's numerous ways to specify this, but lets try a straight-forward one. To avoid the arithmetic of compounding scales, lets specify a dimension, a pixel change and a duration. For example...
#[ #{#"dimension":#"width", #"delta":#10, #"duration":0.2},
#{#"dimension":#"both", #"delta":#40, #"duration":0.8},
#{#"dimension":#"width", #"delta":#10, #"duration":0.2} ]
... means a longer change in width straddling a shorter change in height. You can see how this can be a pretty complete language to get done what you want.
We need an animation method that will perform the changes serially. A simple way to do this is to treat the array of actions as a to-do list. The recursive algorithm says: to do a list of things, do the first one, then do the rest....
- (void)animateView:(UIView *)view actions:(NSArray *)actions completion:(void (^)(BOOL))completion {
if (actions.count == 0) return completion(YES);
NSDictionary *action = actions[0];
NSArray *remainingActions = [actions subarrayWithRange:NSMakeRange(1, actions.count-1)];
[self animateView:view action:action completion:^(BOOL finished) {
[self animateView:view actions:remainingActions completion:completion];
}];
}
For the animation, you probably want to use a linear timing curve for the intermediate animations, though I can see you getting more elaborate and change the timing curve at the start and end of the list.
- (void)animateView:(UIView *)view action:(NSDictionary *)action completion:(void (^)(BOOL))completion {
NSString *dimension = action[#"dimension"];
CGFloat delta = [action[#"delta"] floatValue];
NSTimeInterval duration = [action[#"duration"] floatValue];
CGRect frame = view.frame;
if ([dimension isEqualToString:#"width"]) {
frame = CGRectInset(frame, -delta, 0);
} else if ([dimension isEqualToString:#"height"]) {
frame = CGRectInset(frame, 0, -delta);
} else {
frame = CGRectInset(frame, -delta, -delta);
}
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
view.frame = frame;
} completion:completion];
}
If the array of dictionaries is too clumsy to specify (and it is rather general), you could add some convenience methods on top that provide some simpler scheme to the caller and builds the array of more general representation.

Animating while resizing a view

I have a view containing many bubbles of various sizes. I am trying to create an animation that will zoom into a bubble, making it the same size every time, and center it in my view. This would cause all the bubbles to zoom until the bubble in question is the right size. The bubbles should all maintain the same ratio throughout the process so that if one bubble moves, all the others move the same amount and in the same direction. If one grows, they all grow in proportion.
I have gotten as far as creating the animation to center the bubble and all the other bubbles move proportionally. The problems arise when I try to make the bubbles grow. Once I add the line bellow which does successfully make the bubbles grow in proportion, the code to move the bubble to center the bubbles no longer moves the bubble to the right point. I cannot figure out how to make the bubble both grow and move to the right position.
To move the bubbles (Needs to be 22p from the top and centered horizontally, and 64p by 64p in size), this successfully moves the bubbles to the right position without growing them to the correct size:
float distanceFromTop = 22 - bubble.frame.origin.y;
float distanceFromLeft = self.frame.size.width / 2 - bubble.center.x;
[UIView animateWithDuration:1 animations:^{
self.currentKarmaView.frame = CGRectMake(distanceFromLeft, distanceFromTop, self.currentKarmaView.frame.size.width, self.currentKarmaView.frame.size.height);
}];
To make the bubbles grow, I added the following line, which should make the bubbles grow and move them to the right position. With growth added, the bubbles still move, just not to the right position.
float distanceFromTop = 22 - bubble.frame.origin.y;
float distanceFromLeft = self.frame.size.width / 2 - bubble.center.x;
[UIView animateWithDuration:1 animations:^{
self.currentKarmaView.frame = CGRectMake(distanceFromLeft, distanceFromTop, self.currentKarmaView.frame.size.width, self.currentKarmaView.frame.size.height);
self.currentKarmaView.transform = CGAffineTransformScale(CGAffineTransformIdentity, scaleFactor, scaleFactor);
}];
I have tried many many variations of this, but cannot get the growth and positioning to work in unison. If anyone can help, I would really appreciate it.

How to animate a search field expanding from right to left in iOS

What I'm trying to reach is similar to what is implemented on youTube app on iPad. The search field is expanding in animation from right to left. I'm trying to do so and i'm getting very strange and not smooth animation, Although left to right is working perfect.
|<-------------------------------|Search Field|
It seems that the origin value is changed first and than the width changed , un like the left-right expanding animation that the origin stays the same.
Thanks
You can use animation just put Search field in dynamically in view and put below code.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30];
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame;
CGRect frTblNote = tblNotes.frame;
frGnrVw.size.height = 0.0;
frGnrVw.size.height += 78.0;
generalView.frame = frGnrVw;
[UIView commitAnimations];
In above code general view is my view which has hight 0 and when some action called at that time view height increase and and we will see that view expanding down in that i can not change view's x and y position But in your case first hide your view and when search action calls set hidden NO of your view and in my code i increase height so you can increase your width and also change it's x position means (decrese) i.e you increase width 320 than you decrese it x position to 320 .
just try it it will work.
you can also put it statically in your story board or in nib just set its width =0 and x= 320.
you have to do like below.
[UIView beginAnimations : #"Display notif" context:nil];
[UIView setAnimationDuration:0.30]; // set duration of animation in seconds.
[UIView setAnimationBeginsFromCurrentState:FALSE];
CGRect frGnrVw = generalView.frame; //get frame of view.
frGnrVw.size.width = 0.0;
frGnrVw.size.width += 320.0;//increase width.
frGnrVw.origin.x -=320.0; // decrese position.
generalView.frame = frGnrVw; //set new frame to view.
[UIView commitAnimations]; // this will require.
you just put your view with search field at the position x=320 ,y = as your requirement ,width = 0 and height = as your requirement.
try it it will work.
Also you can hide like same in reverse order.
means increase its x position and decrease its width with above code.
If my answer helps than please vote up my answer.

Mirroring UIViews

I am working on an application that supports multiple languages. In order to support languages that start from right to left, I am transforming the view so that views on the right side get shifted to left side as shown in the images below:
I am using the following code to transform the view
self.view.transform = CGAffineTransformMakeScale(-1, 1);
What I now want to do is transform the views in its new position in the left to remove the mirrored text. For example, I want to flip the "FLIP LABEL" about its center so that the text is displayed properly. How do I do this?
You could try running the same transform again on the individual subviews - for example:
for (UIView *view in self.view.subviews) {
view.transform = CGAffineTransformMakeScale(-1, 1);
}
(Or maybe it would be CGAffineTransformMakeScale(1, 1)? I'm not totally sure.)

Resources