Vanishing popup alert view - ios

I'd like to popup a view with a single label in it that disappears slowly within one second to inform the user about a choice he made, an update occurred or whatever.
I use animatewithduration, but because they may be many different alerts, I'd like to create a class to avoid creating view, label and func in any UIViewController that may display that kind of alert ... Kind of :
let doneAlert = PopUpAlert(parentView : self, textAlert : "You're done")
where parentView in the view where I want the textAlert to be displayed and then when needed:
doneAlert.display()
Here's the class I wrote :
class PopUpAlert: UIView {
convenience init(parentView : UIView,textAlert : String) {
self.init(frame: CGRect(x: 0, y: 0, width: 200, height: 150))
self.alpha = 0
self.center = parentView.center
let popUpLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 150))
popUpLabel.center = self.center
popUpLabel.text = textAlert
self.addSubview(popUpLabel)
parentView.addSubview(self)
}
func display() {
PopUpAlert.animateWithDuration(0.5, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.alpha = 1.0
}, completion: nil)
PopUpAlert.animateWithDuration(1.0, delay: 0.5, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.alpha = 0.0
}, completion: nil)
}
}
And here's the way I use it :
class CarteVC: UIViewController {
var daddy : RootViewController?
var goAlert : PopUpAlert?
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
goAlert = PopUpAlert(parentView: mapView, textAlert: "On the way ....")
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let bb = UIBarButtonItem(title: "< List", style: .Plain, target: papa!, action: "pred")
bb.tintColor = UIColor.lightGrayColor()
daddy!.navigationItem.leftBarButtonItem = bb
daddy!.navigationItem.rightBarButtonItem = nil
goAlert!.display()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Navigation
Nothing is displayed.

If you want to just alert user and disappear in one second than i would suggest you to use Toast Swift
https://github.com/scalessec/Toast-Swift
Here is how you make the toast
self.view.makeToast("Testing Toast")
// specific duration and position
self.view.makeToast("Testing Toast with duration and position", duration: 3.0, position: .Top)
// toast with image and all possible
self.view.makeToast("testing toast image and all possible ", duration: 2.0, position: CGPoint(x: 110.0, y: 110.0), title: "Toast Title", image: UIImage(named: "toast.png"), style:nil) { (didTap: Bool) -> Void in
if didTap {
print("with tap")
} else {
print("without tap")
}
}

The pb came from centering the label inside the view ... Here's the class and works perfectly fine !!! :
class PopUpAlert: UIView {
convenience init(parentView : UIView,textAlert : String) {
self.init(parentView: parentView,textAlert: textAlert,background: UIColor.darkGrayColor(),foreground: UIColor.whiteColor())
}
convenience init(parentView : UIView,textAlert : String, background : UIColor) {
self.init(parentView: parentView,textAlert: textAlert,background: background,foreground: UIColor.whiteColor())
}
convenience init(parentView : UIView,textAlert : String, foreground : UIColor) {
self.init(parentView: parentView,textAlert: textAlert,background: UIColor.darkGrayColor(),foreground: foreground)
}
convenience init(parentView : UIView,textAlert : String, background : UIColor, foreground : UIColor) {
self.init(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
self.alpha = 0
self.backgroundColor = background
self.layer.cornerRadius = 5
self.layer.masksToBounds = true
self.center = (parentView.superview ?? parentView).center
let popUpLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 40))
popUpLabel.textAlignment = .Center
popUpLabel.textColor = foreground
popUpLabel.text = textAlert
self.addSubview(popUpLabel)
parentView.addSubview(self)
}
deinit {
self.removeFromSuperview()
}
func display() {
PopUpAlert.animateWithDuration(0.5, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.alpha = 0.85
}, completion: nil)
PopUpAlert.animateWithDuration(1.0, delay: 0.7, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.alpha = 0.0
}, completion: nil)
}

Related

Wait until the user touches the screen. Swift

After something happens I make a view appear with a label,
let myView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
let label = UILabel(frame: CGRect(x:0,y:0,width: 100, height: 100))
myView.addSubview(lebel)
self.view.addSubview(myView)
myView.alpha = 0
UIView.animate(withDuration: 0.5, animations: {
myView.alpha = 1
})
Now I want you to wait until a tap is made on the screen, and then
UIView.animate(withDuration: 0.5, animations: {
muView.alpha = 0
}, completion: { (bool) in
myView.removeFromSuperview()
})
How can I wait until I touch the screen?
Just add tapGesture to Your View
At viewDidload
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
self.view.addGestureRecognizer(tapGesture)
handleTapGesture
#IBAction func handleTapGesture(_ recognizer: UITapGestureRecognizer) {
UIView.animate(withDuration: 0.5, animations: {
muView.alpha = 0
}, completion: { (bool) in
myView.removeFromSuperview()
})
}
In addtion to Abdelahad's answer, you should declare let myView as a property to use it within #IBAction func handleTapGesture(_ recognizer: UITapGestureRecognizer) {}. So, the new code is the following:
#IBAction func handleTapGesture(_ recognizer: UITapGestureRecognizer) {
UIView.animate(withDuration: 0.5, animations: {
self.myView.alpha = 0
}, completion: { (bool) in
self.myView.removeFromSuperview()
})
}
Finally adding, I found your slight mistake in your code. muView is wrong and myView is correct.

My pan gesture recognizer is very slow and unresponsive

I have a pan gesture recognizer in my app that does a function when swiped down. The animation used to be smooth but all of a sudden (without adding an code to that view controller) it becomes very laggy and I have to swipe down quickly for it to do that animation, It doesn't follow my finger.
What is the cause of that
class PhotoViewController: UIViewController, CLLocationManagerDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
override var prefersStatusBarHidden: Bool {
return true
}
private var backgroundImage: UIImage
private var backgroundImageView: UIImageView?
private var picker: UIPickerView
var list: [String]
var locationPicked: String
var locationArray: [Any]
var partyIndex: Int = Int()
init(image: UIImage) {
self.backgroundImage = image
self.picker = UIPickerView()
self.list = ["Loading..."]
self.locationPicked = list[0]
self.locationArray = []
super.init(nibName: nil, bundle: nil)
print(image)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
/************************************/
override func viewDidLoad() {
super.viewDidLoad()
if Reachability.isConnectedToNetwork() == true{
mapApi()
}
let backgroundImageView = UIImageView(frame: view.frame)
backgroundImageView.image = backgroundImage
backgroundImageView.isUserInteractionEnabled = true
self.backgroundImageView = backgroundImageView
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureRecognizerAction(_:)))
backgroundImageView.addGestureRecognizer(panGestureRecognizer)
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap(sender:)))
backgroundImageView.addGestureRecognizer(longGesture)
view.addSubview(backgroundImageView)
view.backgroundColor = greenColor
picker.dataSource = self
picker.delegate = self
picker.frame = CGRect(x: ((self.view.frame.width)/2)-84, y: (self.view.frame.height)-70, width: 160, height: 40)
picker.clipsToBounds = true
picker.layer.cornerRadius = picker.bounds.size.width/20
picker.layer.borderColor = redColor.cgColor
picker.layer.borderWidth = 0
picker.backgroundColor = UIColor(colorLiteralRed: 217/255, green: 83/255, blue: 79/255, alpha: 0.85)
backgroundImageView.addSubview(picker)
print(list)
}
func panGestureRecognizerAction(_ gesture: UIPanGestureRecognizer){
let translation = gesture.translation(in: view)
if let bgImage = gesture.view{
if list.count > 1{
bgImage.frame.origin.y = translation.y
}
}
if gesture.state == .ended{
let tickName = "Tick.png"
let tickImage = UIImage(named: tickName)
let tick = UIImageView(image: tickImage!)
tick.frame = CGRect(x: ((self.view.frame.width)/2)-25, y: 150, width: 70, height: 70)
self.view.addSubview(tick)
tick.alpha = 0
let crossName = "Cross.png"
let crossImage = UIImage(named: crossName)
let cross = UIImageView(image: crossImage!)
cross.frame = CGRect(x: ((self.view.frame.width)/2)-25, y: (self.view.frame.height)-75, width: 50, height: 50)
self.view.addSubview(cross)
cross.alpha = 0
let velocity = gesture.velocity(in: view)
if (gesture.view?.frame.origin.y)! > CGFloat(100) || velocity.y > 1500 {
UIView.animate(withDuration: 0.4, animations: {
self.view.backgroundColor = greenColor
gesture.view?.frame.origin = CGPoint(x: 0, y: 275)
tick.alpha = 1
}, completion: { (true) in
UIView.animate(withDuration: 0.4, delay: 0.2, animations: {
tick.alpha = 0
})
if partyAt != nil{
self.uploadPartyPost()
} else{
self.uploadPost()
}
})
UIView.animate(withDuration: 0.5, delay: 1, animations: {
gesture.view?.frame.origin = CGPoint(x: 0, y: 0)
}, completion: { (true) in
self.dismiss(animated: true, completion: nil)
})
//send image here tick
} else if (gesture.view?.frame.origin.y)! < CGFloat(-80) || velocity.y > 1500 {
UIView.animate(withDuration: 0.2, animations: {
self.view.backgroundColor = redColor
gesture.view?.frame.origin = CGPoint(x: 0, y: -150)
cross.alpha = 1
}, completion: { (true) in
UIView.animate(withDuration: 0.5, delay: 0.7, animations: {
cross.alpha = 0
})
})
UIView.animate(withDuration: 0.2, delay: 1, animations: {
gesture.view?.frame.origin = CGPoint(x: 0, y: 0)
}, completion: { (true) in
self.dismiss(animated: true, completion: nil)
})
print("Done")
//send image here cross
} else {
UIView.animate(withDuration: 0.3, animations: {
gesture.view?.frame.origin = CGPoint(x: 0, y: 0)
})
}
}
}
After playing with translation of Pan gesture you need to set translation point back to zero.

UIGestureTap to dismiss view

I am trying to enable UIGestureTap on a custom view. I have a view controller, and in that view controller, when I press a button, a custom view pops up.
var transparentBackground = UIView()
#IBAction func UserViewImage(_ sender: UIButton) -> Void {
self.transparentBackground = UIView(frame: UIScreen.main.bounds)
self.transparentBackground.backgroundColor = UIColor(white: 0.0, alpha: 0.4)
UIApplication.shared.keyWindow!.addSubview(self.transparentBackground)
self.opaqueView = self.setupOpaqueView()
self.transparentBackground.addSubview(opaqueView)
UIApplication.shared.keyWindow!.bringSubview(toFront: self.transparentBackground)
self.view.bringSubview(toFront: transparentBackground)
}
I want to be able to tap on the transparentBackground view and dismiss it. So I have a dismiss function called removeAnimate()
func removeAnimate()
{
UIView.animate(withDuration: 0.25, animations: {
self.transparentBackground.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.transparentBackground.alpha = 0.0;
}, completion:{(finished : Bool) in
if (finished)
{
self.transparentBackground.removeFromSuperview()
}
});
}
So, in viewdidload I enabled the UITapGesture:
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(removeAnimate))
self.transparentBackground.addGestureRecognizer(gestureRecognizer)
self.transparentBackground.isUserInteractionEnabled = true
I know the function removeAnimate works because I used it on a button in the transparentBackground view and it works perfectly. But when I tap on the transparentBackground view it does not dismiss and I am not sure what I am doing wrong
func setupOpaqueView() -> UIView{
let mainView = UIView(frame: CGRect(x: 16, y: 132, width: Int(UIScreen.main.bounds.width-32), height: 403))
mainView.backgroundColor = UIColor.clear
mainView.layer.cornerRadius = 6
self.imageView = UIImageView(frame: CGRect(x: 29, y: 18, width: 274, height: 350))
mainView.addSubview(OKbutton)
mainView.addSubview(self.imageView)
OKbutton.addTarget(self, action: #selector(ThirdWheelViewController.handleOKButtonTapped(_:)), for: .touchUpInside)
return mainView
}
This is an example and hope it helps you:
First of all create a variable:
var customView:UIView!
This is going to be our function for adding a custom view:
#IBAction func customAction(_ sender: AnyObject) {
self.customView = UIView.init(frame: CGRect.init(x: self.view.bounds.width / 2, y: self.view.bounds.height / 2, width: 100, height: 100))
self.customView.backgroundColor = UIColor.red
self.view.addSubview(self.customView)
let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.removeFromSuperView))
tap.numberOfTapsRequired = 1
self.customView.addGestureRecognizer(tap)
}
And finally:
func removeFromSuperView() {
self.customView.alpha = 1.0
self.customView.transform = .identity
UIView.animate(withDuration: 0.3, animations: {
self.customView.alpha = 0.0
self.customView.transform = .init(scaleX: 1.5, y: 1.5)
}) { (finished) in
if !finished {
} else {
self.customView.removeFromSuperview()
}
}
}

Animation: continuous heartbeat monitor lines

I have an image of what symbolises a heartbeat
and I'm trying to loop it in my subview so it continuously appears on my view if you understand what i mean. So far I have got it to appear and move across infinitely on my subview however it isn't continuous as it only appears again from the left after it has completely gone out of the view on the right where as I want it to appear again as soon as it has completely entered the view so it symbolises an actual heartbeat. My code looks something like this on my viewDidLoad:
self.heartbeatLoading.frame.origin = CGPoint(x: 0 - heartbeatLoading.frame.size.width, y: 10)
let animation: UIViewAnimationOptions = [.repeat, .curveLinear]
UIView.animate(withDuration: 5.0, delay: 0, options: animation, animations: {
self.heartbeatLoading.frame = self.heartbeatLoading.frame.offsetBy(dx: self.view.frame.width + self.heartbeatLoading.frame.width, dy: 0.0)
}, completion: nil)
Take one UIView and set this class as a super view. Call start animation and stop the animation whenever required.
#IBDesignable class Pulse : UIView
{
var animatingView : UIView?
#IBInspectable var pulseImage: UIImage = UIImage(named: "defaultImage")!{
didSet {
animatingView = UIView(frame: self.bounds)
let imgView = UIImageView(frame : self.bounds)
animatingView?.clipsToBounds = true
animatingView?.addSubview(imgView)
self.addSubview(animatingView!)
}
}
func startAnimationWith(duration : Double = 0.5)
{
if animatingView != nil
{
animatingView?.frame = CGRect(x: 0, y: 0, width: 0, height: (animatingView?.frame.size.height)!)
UIView.animate(withDuration: duration, delay: 0, options: .repeat, animations: {
self.animatingView?.frame = CGRect(x: 0, y: 0, width: (self.animatingView?.frame.size.width)!, height: (self.animatingView?.frame.size.height)!)
}, completion: { (isDone) in
})
}
}
func stopAnimation()
{
if animatingView != nil
{
self.animatingView!.layer.removeAllAnimations()
}
}
override init(frame : CGRect) {
super.init(frame : frame)
}
convenience init() {
self.init(frame:CGRect.zero)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}

IOS set UIViewController.view.frame = CGCGRect(x: -200..) can not click button

I want put several UIViewController together:
leftViewController.view.frame = CGRect(x: -200, y: 0.0, width: size.width/drawerSize, height: size.height)
// Center Drawer
centerViewController.view.frame = CGRect(x: leftViewController.view.frame.width, y: 0.0, width: centerWidth, height: size.height)
// Right Drawer
rightViewController.view.frame = CGRect(x: centerViewController.view.frame.origin.x + centerViewController.view.frame.size.width, y: 0.0, width: size.width/drawerSize, height: size.height)
In the first line I use
leftViewController.view.frame = CGRect(x: -200, y....)
They will show correctly but I can not click buttons on leftViewController.
If
leftViewController.view.frame = CGRect(x: 0.0, y...)
then could click button but this layout is not I want.
The full code is posted by #Kevin Scardina Slide Sidebar Menu IOS 8 Swift
It now function as the picture below, And I'm trying to modify it like a slide menu bar which could hid left and right menu.
/*
To use simply instantiate NVMDrawerController as your root view in your AppDelegate, or in the
StoryBoard.
Once NVMDrawerController is instantiated, set the drawerSize of the NVMDrawerController,
and its leftViewControllerIdentifier, centerViewControllerIdentifier, and
rightViewControllerIdentifier to the Storyboard Identifier of the UIViewController
you want in the different locations.
*/
class NVMDrawerController: UIViewController {
// This is where you set the drawer size (i.e. for 1/3rd use 3.0, for 1/5 use 5.0)
var drawerSize:CGFloat = 4.0
var leftViewControllerIdentifier:String = "LeftController"
var centerViewControllerIdentifier:String = "CenterController"
var rightViewControllerIdentifier:String = "RightController"
private var _leftViewController:UIViewController?
var leftViewController:UIViewController {
get{
if let vc = _leftViewController {
return vc;
}
return UIViewController();
}
}
private var _centerViewController:UIViewController?
var centerViewController:UIViewController {
get{
if let vc = _centerViewController {
return vc;
}
return UIViewController();
}
}
private var _rightViewController:UIViewController?
var rightViewController:UIViewController {
get{
if let vc = _rightViewController {
return vc;
}
return UIViewController();
}
}
static let NVMDrawerOpenLeft = 0
static let NVMDrawerOpenRight = 1
var openSide:Int {
get{
return _openSide;
}
}
private var _openSide:Int = NVMDrawerOpenLeft
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Instantiate VC's with storyboard ID's
_leftViewController = instantiateViewControllers(leftViewControllerIdentifier)
_centerViewController = instantiateViewControllers(centerViewControllerIdentifier)
_rightViewController = instantiateViewControllers(rightViewControllerIdentifier)
// Call configDrawers() and pass the drawerSize variable.
drawDrawers(UIScreen.mainScreen().bounds.size)
self.view.addSubview(leftViewController.view)
self.view.addSubview(centerViewController.view)
self.view.addSubview(rightViewController.view)
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in
// This is for beginning of transition
self.drawDrawers(size)
}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
// This is for after transition has completed.
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Drawing View
func drawDrawers(size:CGSize) {
// Calculate Center View's Size
let centerWidth = (size.width/drawerSize) * (drawerSize - 1)
// Left Drawer
leftViewController.view.frame = CGRect(x: 0.0, y: 0.0, width: size.width/drawerSize, height: size.height)
// Center Drawer
centerViewController.view.frame = CGRect(x: leftViewController.view.frame.width, y: 0.0, width: centerWidth, height: size.height)
// Right Drawer
rightViewController.view.frame = CGRect(x: centerViewController.view.frame.origin.x + centerViewController.view.frame.size.width, y: 0.0, width: size.width/drawerSize, height: size.height)
//rightViewController = rc
// Capture the Swipes
let swipeRight = UISwipeGestureRecognizer(target: self, action: Selector("swipeRightAction:"))
swipeRight.direction = .Right
centerViewController.view.addGestureRecognizer(swipeRight)
let swipeLeft = UISwipeGestureRecognizer(target: self, action: Selector("swipeLeftAction:"))
swipeLeft.direction = .Left
centerViewController.view.addGestureRecognizer(swipeLeft)
if(openSide == NVMDrawerController.NVMDrawerOpenLeft){
openLeftDrawer()
}
else{
openRightDrawer()
}
}
// MARK: - Open Drawers
func openLeftDrawer() {
_openSide = NVMDrawerController.NVMDrawerOpenLeft
UIView.animateWithDuration(0.1, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations:
{ () -> Void in
// move views here
self.view.frame = CGRect(x: 0.0, y: 0.0, width: self.view.bounds.width, height: self.view.bounds.height)
}, completion:
{ finished in
})
}
func openRightDrawer() {
_openSide = NVMDrawerController.NVMDrawerOpenRight
UIView.animateWithDuration(0.1, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations:
{ () -> Void in
// move views here
self.view.frame = CGRect(x: self.view.bounds.origin.x - self.leftViewController.view.bounds.size.width, y: 0.0, width: self.view.bounds.width, height: self.view.bounds.height)
}, completion:
{ finished in
})
}
// MARK: - Swipe Handling
func swipeRightAction(rec: UISwipeGestureRecognizer){
self.openLeftDrawer()
}
func swipeLeftAction(rec:UISwipeGestureRecognizer){
self.openRightDrawer()
}
// MARK: - Helpers
func instantiateViewControllers(storyboardID: String) -> UIViewController {
if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("\(storyboardID)") as? UIViewController{
return viewController;
}
return UIViewController();
}
}
When your view is outside of its superview,it can't receive any touch events.You should enumerate subviews in UIView(its superview) touchWithEvents function and make it receive the event.

Resources