Replicate iOS 8.4 music app search animation - ios

I am making an app with a search button in the nav bar. I would like to replicate the search animation in the music app.
I would like to press search and have the search bar come in from the top, and the table view to fade in.
Is there an easy way to do this?

I believe its pretty simple
It is actually a different view that is sliding down.
So essentially create a view with everything you want on it. Like the textField, the cancel button, etc.
This view when it is created needs to appear above your mainView.
So the y value on your frame will be 0 minus your new view height.
When you are ready for the view to appear use UIView.animateWithDuration to change your views frame y value to 0
UIView.animateWithDuration(2, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: {
myView.frame = CGRectMake(0, myView.frame.origin.y + myView.frame.height, 100, 100)
//could also just set the y value to 0 but I included the origin/height part to help you understand
}, completion: {
(value: Bool) in
})

Related

Show No Internet Connection Message Like Instagram

I was wondering how can i show a 'No Internet Connection' Just how like Instagram does it,
As an Example :
That see-through custom message animating to show under the navigationController . Would really love to get this to my project ,
thank you for you help
So here's a pic of the storyboard like this :-
"No internet connection" is a label, and the red view underneath is just to test the see through property of the label. If you are designing the UI in code, you can probably make a label similar to mine and place it to the top of the Navigation bar by using it's frame property.
The button here I'm using is just to show the label pop up on the scene (since it's just a demo answer). In your case, if the internet is not available, you will proceed to show the pop up.
So if you are making the UI in code, make sure to make the label in the viewDidLoad method. I have made an IBOutlet and the viewDidLoad now looks like this:-
override func viewDidLoad() {
super.viewDidLoad()
let transform = CGAffineTransform(translationX: 0, y: -label.frame.height)
label.alpha = 0
label.transform = transform
}
On the view loading, I'm moving the label behind the navigation bar, using CGAffineTransform. The distance, how much to move up is the label's height, since we don't want any part to be clipped on the scene.
Next step, is just a fix. I'm making alpha = 0, because navBar is translucent is nature and hence will change it's colour, since our label is behind it. So setting alpha to 0, takes care of it, and in third step apply the transform.
Now, if the internet connection is not available, we should pop out the label under the navBar. The code will look something like this:-
fun checkInternet() {
// called by some of your observer, which checks for changes in internet connection
if !isInternetAvailable {
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveLinear, animations: {
self.label.alpha = 0.5
self.label.transform = .identity
}, completion: nil)
}
}
So here, I'll show the pop up with an animation using UIView.animate with some spring damping, so it has a nice bouncy effect to it. I'm setting the alpha to 0.5, since you mentioned you want a see through label, and I'm setting the label to a transform which will bring it back to it's original position when it was created, that's why I'm using .identity.
You can play around usingSpringWithDamping values and change options to have different effects.

Not all content is animated inside a stack view when hiding it

I'm currently working on a iOS (swift 3) app. I have a simple vertical stack view containing 2 horizontal stack views. In some cases I want to hide the bottom one. I do so by using the following code
UIView.animate(withDuration: 3) {
self.bottomStackView.isHidden = true;
};
The animation shown below doesn't really do what I would expect:
While the border of the buttons is animated properly when hiding, the text inside each button doesn't seem to be affected until the very end. Any idea as to how I could fix this?
I kept doing some research on the subject, and it seems like most articles were suggesting that using stacks to perform animation would work fine. However I have also found that animations would only work with animatable properties, isHidden not being one of them.
In the end after some trial and errors I have found that isHidden can be animated with stack views, but you can expect children to misbehave. So far the only workaround I have found is like so:
let duration = 0.5;
let delay = 0;
UIView.animate(withDuration: duration, delay: delay, animations: {
self.bottomStack.isHidden = self.hideBottomStack;
})
UIView.animate(withDuration: duration/2, delay: delay, animations: {
self.bottomStack.alpha = 0;
})
You'll note here that I basically "turn" the alpha property down to 0 in half the time I take to hide the stack. This has the effect to hide the text before it overlaps with the upper stack. Also note that I could also have decided to do something like this:
UIView.animate(withDuration: duration, delay: delay, animations: {
self.bottomStack.alpha = 0;
}, completion: { (_) in
self.bottomStack.isHidden = true;
})
This would also hide the bottom stack, but you lose the hiding motion in favor of a fading motion and hide the stack once the fading is done.
I'm not sure about this, I think stackviews can cause weird behaviour sometimes. Have you tried adding "self.view.layoutIfNeeded()" inside the UIView.animate block? Like this:
UIView.animate(withDuration: 3) {
self.bottomStackView.isHidden = true
self.view.layoutIfNeeded()
}
I think it should also work if you put the "self.bottomStackView.isHidden = true" above the UIView.animate, not sure though, not an expert at it.
Also, I don't think you need to use ";" after your line of code in swift :)

How to compare if the coordinates are equal to the original coordinates of an object

Can someone please help me??
Lets start with the main information: I created an app that has a 2 view and one is called InfoView. This InfoView is located off screen with the following code:
(Code Hide View)
UIView.animateWithDuration(1.0, delay: 0.3, options: [ ], animations: {self.InfoView.center.x -= self.view.bounds.width + 150}, completion: nil)
Its automatically moved when the app starts. I placed the Code Hide View on ViewDidAppear.
When the button Info is pressed the InfoView ease in from left to right to its original coordinates, (As I placed it on the storyboard with x=12 and y=20 and the Views size depends on the screen size). I use the following code to bring it back.
(Code Show View)
UIView.animateWithDuration(1.0, delay: 0.0, options: [ ], animations: {self.InfoView.center.x += self.view.bounds.width + 150}, completion: nil)
The InfoView has a button that when pressed hides the view (Code Hide View) once again so that its off screen.
My problem is that when I tryout the app if the Iphone receives a call (phone call or sms or etc), after the call had ended it would show the InfoView on screen and without pressing the Show View Code to run.
Ive then hidden the view with:
InfoView.Hidden = True
And when I run the Show View code it changes to false and when it hides it turns to true and so on. However now when I receive a call and after the call has ended One can't see the InfoView (Thats good) although If I press the show Info Button the InfoView will appear suddenly on screen and ease out the right side of the screen, making it unreachable (off screen).
My question is there a way to compare the InfoView coordinates so that if its on Screen (And I haven't called it, run the show View) it could be sent back off screen. Like with an if statement. for example like:
if InfoView == CGPoint(12,20).... //(Then Run Hide View)
(I know the if statement is wrong) And I do understand that I got to run that func in the app delegate in the applicationWillResignActive.
Please can someone help me, am I on the right track or can someone give me another solution. (Tell Me If I need to explain it better)
You should compare it by below way. Do not comapre with hardcoded point.
if(InfoView.center.x > self.view.bounds.width)
{
//infoview is hidden
}
else
{
//infoview is visible
}

Prevent click through view in swift

I'm working in Xcode and swift, I created a view acting as a menu that toggles on tap, when the menu comes out I can still click a test button underneath it. I don't want that to happen. I want everything behind the view to be disabled giving priority to the menu view. (View Image below)
screenshot from the sample app
Keep in mind that I'm not considering one button, if that was the case I would've disabled that specific button. This page will be a scroll view and it will be dynamic.
this is the code that I'm using:
#IBAction func MenuButton(sender: UIButton) {
if self.MenuView.frame.origin.x == -180 {
UIView.animateWithDuration(0.5, animations:{
self.MenuView.frame = CGRectMake(self.MenuView.frame.origin.x + 180, self.MenuView.frame.origin.y, self.MenuView.frame.size.width, self.MenuView.frame.size.height)
})
} else {
UIView.animateWithDuration(0.5, animations:{
self.MenuView.frame = CGRectMake(self.MenuView.frame.origin.x - 180, self.MenuView.frame.origin.y, self.MenuView.frame.size.width, self.MenuView.frame.size.height)
})
}
}
the view is hidden 180 pixels on the left side, when the menu button is clicked the view will animate 180 pixels to the right which brings it to the front. The function checks if the view is already opened so it can animate it back 180 pixel to hide it.
The only thing I need is to disable clicking through the view.
Swift 3 version that worked great for me in stopping the click through (thanks to the previous comment by #Ismail).
myAddedSubView.isUserInteractionEnabled = true
This is the 'simple, one-line' answer and works like z index (presuming you wanted the z index to be 'absolute top'.
The fact that the button is still visible and clickable means that it must be in front of the menu. If you rearrange the order of things so that the menu is in front of the button, then you should get the result that you are looking for.

iOS custom UIView as input keyboard [duplicate]

This question already has answers here:
How to create a custom keyboard
(5 answers)
Closed 6 years ago.
I have huge issues when trying to use a custom view as a input keyboard for a text field.
The setup is pretty simple (for testing) : I have a UIView with one button, half the size of the screen and a text field somewhere above it.
I set up a dummy view to be the input view of the text field like so let dummyView : UIView = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1))
Also I added the following setting on viewDidAppear testView.frame.origin.y = view.bounds.height. This is of course ignored as the view appears on screen (putting it on viewDidLoad leads to same behaviour). However, putting it in viewdidLayoutSubviews leads to a very strange behaviour, the view does not appear on screen, but trying to animate to, let's say a 380 origin.y does nothing.
The best part is yet to come: if I hide the view, then the slide up animation (code bellow)
UIView.animateWithDuration(0.6, animations: {
self.testView.frame = self.whereToBe!
}, completion: {
finished in
if finished {
}
})
works just fine. However, trying to slide it down again and resigningFirstResponder on the text field on button press (code bellow)
UIView.animateWithDuration(0.6, animations: {
//self.testView.frame = self.whereToBe!
self.testView.frame.origin.y = self.view.frame.height
}, completion: {
finished in
if finished {
self.view.endEditing(true)
//self.inputField.resignFirstResponder()
self.testView.hidden = true
}
})
shows a fascinating wrong behaviour: the view slides from top to its current position. However, on second press on the button, it works just fine, it slides down BUT it reappears on screen after the animation has completed.
Can you please help me?
Use the view as the inputView of the textfield by simply setting
self.textField.inputView = self.pickerView;
and avoid all these custom animations.

Resources