Prevent click through view in swift - ios

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.

Related

How to implement horizontal stacked cards which moves from left to right when we swipe?

I want to show horizontal stacked cards , which moves one by one from left to right by swipe action . Once a card moves it forms a stack on the right side
I have tried seeing various libraries which straight away does not implement this. https://www.cocoacontrols.com/controls/iaccordion this one came close it has vertical swipe and is in objective C. Can you point me in the right direction to get this done ?
Card-like stacks are very easy to make but can be hard to perfect when it comes to some effects. Basically each of your views has one of 3 possible positions; on initial stack, on target stack, user is dragging it.
So the simplest implementation is to define 2 centers for your views and have 2 arrays of views. At the beginning all the views are in the first array. All views in first array should be centered to first center and in second array centered to the second center. Now you need a pan gesture. When a gesture starts you should check if it starts on the left stack if it does simply remove it from first array and begin changing its center. Like
func onPanGesture(_ sender: UIGestureRecognizer) {
switch sender.state {
case .began:
if leftStackView.bounds.contains(sender.location(in: leftStackView)), viewsInLeftStack.count > 0 {
pannedView = viewsInLeftStack.removeLast()
}
case .changed:
pannedView?.center = sender.location(in: self.view)
}
}
Now when finger is lifted you should check if card should be put back or moved to the other stack. So another case for gesture recognizer must be added:
case .ended, .cancelled:
if let pannedView = pannedView {
if(abs(pannedView.center.x-leftStackView.center.x) > abs(pannedView.center.x-rightStackView.center.x)) {
// Closer to the right one horizontally
viewsInLeftStack.append(pannedView)
pannedView.center = leftStackView.center
} else {
// Closer to the left one horizontally
viewsInRightStack.append(pannedView)
pannedView.center = rightStackView.center
}
}
In basics that is all you need. But then comes making the component nice. For instance when card is released it should animate to its deck:
UIView.animate(withDuration: 0.3) {
pannedView.center = self.rightStackView.center
}
Then cards may be a bit displaced on both of decks which is easiest to apply some transform. They may even rotate a bit as you drag them... But this is all up to you what you want to implement.

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
}

Replicate iOS 8.4 music app search animation

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
})

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.

How do I move FPPopover as low as I want? If I push it too low, it jumps back to the top

I'm using FPPopover to present a pop over view for my iPhone app. I'm having an issue, however, where when I present it, it will only allow me to present it so low or it will jump to the top. And this is well before it gets cut off anyway.
For example:
[self.speedOptionsPopover presentPopoverFromPoint:CGPointMake(0, 235)];
Works fine, but if I put it a 255 instead of 235 (as it's a good 40px from the bottom) it jumps back up to the top.
Does anyone have any experience with this or how I could fix it?
Also, bonus points if you can explain why the content for the popover always starts like 50px from the top, when I want it to start up higher. How can I change this also?
More code from the creation:
- (void)speedOptionsTapped:(UIBarButtonItem *)sender {
// Set the delegate in the controller that acts as the popover's view to be self so that the controls on the popover can manipulate the WPM and number of words shown
self.speedOptionsController.delegate = self;
self.speedOptionsPopover.arrowDirection = FPPopoverNoArrow;
self.speedOptionsPopover.border = NO;
self.speedOptionsPopover.contentSize = CGSizeMake(320, 190);
[self.speedOptionsPopover presentPopoverFromPoint:CGPointMake(0, 235)];
}
Try replacing this part of the code in FPPopoverController.m:
//ok, will be vertical
if(ht == best_h || self.arrowDirection == FPPopoverArrowDirectionDown)
with this code:
//ok, will be vertical
if (self.arrowDirection == FPPopoverNoArrow)
{
r.origin.x = p.x;
r.origin.y = p.y;
}
else if(ht == best_h || self.arrowDirection == FPPopoverArrowDirectionDown)
The reason you might be having this issue is that the macro FPPopoverArrowDirectionIsVertical considers a popover with no arrows as having a vertical arrow. So, the result is that is tries to best position your popover as close as possible to the view that triggered the popover.
If you replace the code as indicated above, you'll be creating a special case for popovers with no arrows and asking that the original points be respected without repositioning.

Resources