Multi gesture recognizer on one view - ios

My working code slides a label of to the left of the window and slide it again to the right to show it fully. Since I am learning swift, I would appreciate your comments to improve on it. I included some factoring which failed to work.
Working code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myLabel: UILabel!
#IBOutlet var parentView: UIView!
var swipGestureRight: UISwipeGestureRecognizer!
var swipGestureLeft: UISwipeGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myLabel.userInteractionEnabled = true
swipGestureLeft = UISwipeGestureRecognizer(target: self, action: Selector("swipViewLeft:"))
swipGestureLeft.direction = .Left
parentView.gestureRecognizers = [swipGestureLeft]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func swipViewLeft(gesture: UISwipeGestureRecognizer){
UIView.animateWithDuration(0.3, animations: {self.myLabel.center.x -= (self.myLabel.bounds.width)}, completion: nil)
swipGestureRight = UISwipeGestureRecognizer(target: self, action: Selector("swipViewRight:"))
swipGestureRight.direction = .Right
parentView.gestureRecognizers = [swipGestureRight]
}
func swipViewRight(gesture: UISwipeGestureRecognizer){
UIView.animateWithDuration(0.3, animations: {self.myLabel.center.x += (self.myLabel.bounds.width)}, completion: nil)
swipGestureLeft = UISwipeGestureRecognizer(target: self, action: Selector("swipViewLeft:"))
swipGestureLeft.direction = .Left
parentView.gestureRecognizers = [swipGestureLeft]
}
}
Failed after trying to improve:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myLabel: UILabel!
#IBOutlet var parentView: UIView!
var swipGestureRecognizer: UISwipeGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myLabel.userInteractionEnabled = true
swipGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipping:"))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func swipping(gestureRecognizer: UISwipeGestureRecognizer){
if gestureRecognizer.direction == .Left {
parentView.gestureRecognizers = [gestureRecognizer]
UIView.animateWithDuration(0.3, animations: {self.myLabel.center.x -= (self.myLabel.bounds.width)}, completion: nil)
} else {
UIView.animateWithDuration(0.3, animations: {self.myLabel.center.x += (self.myLabel.bounds.width)}, completion: nil)
}
}
}

How about move
parentView.gestureRecognizers = [gestureRecognizer]
to viewDidLoad().

Related

How can I change UIStepper value when changed from UITextField?

I'm very new to all of this and I found some code that got me understanding some of this syntax. I'm trying to create a textfield that lets me type in a value that updates the stepper's value. The stepper currently works (updates the uitextfield) but when I change the value in the textfield it doesn't update the stepper's value, so when I click on the stepper, it reverts back to whatever value it was before I typed in a value... Can anyone tell me why the two functions STracksValueDidChange and CTrackValueDidChange have errors?
Here's my code so far:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var STracks: UITextField!
#IBOutlet weak var STracksStepper: UIStepper!
#IBOutlet weak var CTracks: UITextField!
#IBOutlet weak var CTrackStepper: UIStepper!
override func viewDidLoad() {
super.viewDidLoad()
STracksStepper.autorepeat = true
STracksStepper.maximumValue = 100.0
STracksStepper.minimumValue = 2.0
STracksStepper.stepValue = 2.0
print(STracksStepper.value)
STracks.text = "\(Int(STracksStepper.value))"
STracksStepper.addTarget(self, action: "SstepperValueDidChange:", forControlEvents: .ValueChanged)
STracks.addTarget(self, action: "STextValueDidChange:", forControlEvents: .ValueChanged)
CTrackStepper.autorepeat = true
CTrackStepper.maximumValue = 100.0
CTrackStepper.minimumValue = 2.0
CTrackStepper.stepValue = 2.0
print(CTrackStepper.value)
CTracks.text = "\(Int(CTrackStepper.value))"
CTrackStepper.addTarget(self, action: "CstepperValueDidChange:", forControlEvents: .ValueChanged)
CTracks.addTarget(self, action: "CTextValueDidChange:", forControlEvents: .ValueChanged)
}
//Steppers will update UITextFields
func SstepperValueDidChange(stepper: UIStepper) {
let stepperMapping: [UIStepper: UITextField] = [STracksStepper: STracks]
stepperMapping[stepper]!.text = "\(Int(stepper.value))"
}
func STracksValueDidChange(SText: UITextField) {
let STextMapping: [UITextField: UIStepper] = [STracks: STracksStepper]
STextMapping[SText]!.value = "(SText.text)"
}
func CstepperValueDidChange(stepper: UIStepper) {
let stepperMapping: [UIStepper: UITextField] = [CTrackStepper: CTracks]
stepperMapping[stepper]!.text = "\(Int(stepper.value))"
}
func CTrackValueDidChange(CText: UITextField) {
let CTextMapping: [UITextField: UIStepper] = [CTracks: CTrackStepper]
CTextMapping[CText]!.value = "(CText.text)"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Try something like this.
CTrackStepper.value = Double(Textfield.text)
I am not so sure what the mapping is in your code.
But i don't think you need it for changing the value.
Update, made a project my self:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var textfield: UITextField!
#IBOutlet weak var stepper: UIStepper!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func stepperValueChanged(sender: UIStepper) {
textfield.text = String(sender.value)
}
#IBAction func valueChanged(sender: UITextField) {
if Double(sender.text!) != nil {
stepper.value = Double(sender.text!)!
}
}
}
For steppervaluechanged and valuechanged just drag from uistepper and textfield and choose action and change the Anyobject to Uistepper of Uitextfield.
Good luck :)

how to hide button when clicked from another view

I am a beginner of xcode programming. I am trying to do an action, when i click button from A view, the button of B view will be hidden. I already know i can use button.hidden = true; for self view controller but I don't know how to control button from other view.
Thanks
#IBAction func TestBut(sender: UIButton) {
setting.hidden = false
}
Before, you create a custom view with button, button action and a protocol as:
protocol CustomViewDelegate {
func buttonPressed (sender: AnyObject)
}
class CustomView: UIView {
#IBOutlet weak var button: UIButton!
var delegate: CustomViewDelegate!
override func awakeFromNib() {
super.awakeFromNib()
}
class func loadViewFromXib() -> CustomView {
return NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil)[0] as! CustomView
}
#IBAction func buttonPressed(sender: AnyObject) {
self.delegate.buttonPressed(sender)
}
}
In your ViewController.
class ViewController: UIViewController, CustomViewDelegate {
var firstView: CustomView?
var secondView: CustomView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.firstView = CustomView.loadViewFromXib()
self.secondView = CustomView.loadViewFromXib()
firstView!.frame = CGRectMake(0, 0, 100, 100)
secondView!.frame = CGRectMake(0, 200, 100, 100)
firstView!.delegate = self
secondView!.delegate = self
self.view.addSubview(firstView!)
self.view.addSubview(secondView!)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func buttonPressed(sender: AnyObject) {
if (sender as! UIButton) == self.firstView!.button {
self.secondView?.button.hidden = true
}else {
self.firstView?.button.hidden = true
}
}
}
the button has to be a property of the view( or view controller).
A call would look like this:
view.button.hidden = true

Data can not be saved after the transition between ViewControllers

The purpose for my app
I have two ViewControllers,FrontSideViewController and BackSideViewController, in my little project.
I am about to flipping FrontSideViewController to BackSideViewController through using CATransition while each ViewController's data can be saved.
Describe of Problem
The views transited in the unexpected way which animation is not seem like the UIAnimationTransition.FlipFromLeft(or)Right thing.
After flipping views, the previous view's data can not be saved, which means when I flipped back the old view, its tiny data (something like textField's text) is just gone.
My Code
Same Logical function to flip between the views which be used in two Classes.
FrontSideViewController.swift
class FrontSideViewController: UIViewController {
var frontSideViewController: FrontSideViewController?
var backSideViewController: BackSideViewController?
var frontSide: Bool = true
#IBOutlet weak var flip_1Button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
frontSideViewController = storyboard?.instantiateViewControllerWithIdentifier("FrontSideViewController") as? FrontSideViewController
backSideViewController = storyboard?.instantiateViewControllerWithIdentifier("BackSideViewController") as? BackSideViewController
flip_1Button.addTarget(self, action: "flipViews", forControlEvents: UIControlEvents.TouchUpInside)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func textFieldDoneEditing(sender: UITextField) {
sender.resignFirstResponder()
}
func flipViews() {
UIView.beginAnimations("ViewSwitch", context: nil)
UIView.setAnimationDuration(0.6)
UIView.setAnimationCurve(.EaseInOut)
UIView.setAnimationTransition(.FlipFromLeft, forView: view, cache: true)
backSideViewController?.view.frame = self.view.frame
frontSideViewController?.willMoveToParentViewController(nil)
frontSideViewController?.view.removeFromSuperview()
frontSideViewController?.removeFromParentViewController()
self.addChildViewController(backSideViewController!)
self.view.addSubview(backSideViewController!.view)
backSideViewController?.didMoveToParentViewController(self)
}
}
BackSideViewController.swift
class BackSideViewController: UIViewController {
var frontSideViewController: FrontSideViewController?
var backSideViewController: BackSideViewController?
#IBOutlet weak var flip_2Button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
frontSideViewController = storyboard?.instantiateViewControllerWithIdentifier("FrontSideViewController") as? FrontSideViewController
backSideViewController = storyboard?.instantiateViewControllerWithIdentifier("BackSideViewController") as? BackSideViewController
flip_2Button.addTarget(self, action: "flipViews", forControlEvents: UIControlEvents.TouchUpInside)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func flipViews() {
UIView.beginAnimations("ViewSwitch", context: nil)
UIView.setAnimationDuration(0.6)
UIView.setAnimationCurve(.EaseInOut)
UIView.setAnimationTransition(.FlipFromRight, forView: view, cache: true)
frontSideViewController?.view.frame = self.view.frame
backSideViewController?.willMoveToParentViewController(nil)
backSideViewController?.view.removeFromSuperview()
backSideViewController?.removeFromParentViewController()
self.addChildViewController(frontSideViewController!)
self.view.addSubview(frontSideViewController!.view)
frontSideViewController?.didMoveToParentViewController(self)
}
Please teach me how solve those two problems.
Thanks for your help.
Ethan Joe

Swift - Tap gesture to dismiss keyboard UITableView

I have an identical question to this one , but since I'm new to programming and only really know swift I was wondering if someone could give me its equivalent in swift. Or point me to another question that I may have missed that is in swift.
Thanks!
UPDATE: here's the basic jist of my view controller after I've cut some of the fat away to deal with only the relevant topic. To restate the problem. Not until I have clicked my 'doneButton' to run the createClient() function and navigate back to the client page to edit the freshly created client will the the tap gesture work to dismiss the keyboard.
import UIKit
import CoreData
import Foundation
class NewClientTableViewController: UITableViewController, UINavigationControllerDelegate, UITextFieldDelegate {
let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext
#IBOutlet weak var nameTxt: UITextField!
#IBOutlet weak var ageTxt: UITextField!
#IBOutlet weak var phoneTxt: UITextField!
#IBOutlet weak var emailTxt: UITextField!
#IBOutlet weak var heightTxt: UITextField!
#IBOutlet weak var notesTxt: UITextView!
var client: Client? = nil
override func viewDidLoad() {
super.viewDidLoad()
if client != nil {
nameTxt.text = client?.name
ageTxt.text = client?.age
heightTxt.text = client?.height
phoneTxt.text = client?.phone
emailTxt.text = client?.email
notesTxt.text = client?.notes
self.title = client?.name
phoneTxt.delegate = self
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("hideKeyboard"))
tapGesture.cancelsTouchesInView = true
tableView.addGestureRecognizer(tapGesture)
}
}
func hideKeyboard() {
tableView.endEditing(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func doneButton(sender: AnyObject) {
if client != nil {
editClient()
} else {
createClient()
}
dismissViewController()
}
func editClient() {
client?.name = nameTxt.text
client?.age = ageTxt.text
client?.height = heightTxt.text
client?.phone = phoneTxt.text
client?.email = emailTxt.text
client?.notes = notesTxt.text
client?.clientImage = UIImageJPEGRepresentation(contactImage.image, 1)
managedObjectContext?.save(nil)
}
func createClient() {
let entityDescription = NSEntityDescription.entityForName("Client", inManagedObjectContext: managedObjectContext!)
let client = Client(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext)
if nameTxt.text == "" {
client.name = "Untitled Client"
} else {
client.name = nameTxt.text
}
client.age = ageTxt.text
client.height = heightTxt.text
client.phone = phoneTxt.text
client.email = emailTxt.text
client.notes = notesTxt.text
client.clientImage = UIImageJPEGRepresentation(contactImage.image, 1)
managedObjectContext?.save(nil)
}
func dismissViewController() {
navigationController?.popToRootViewControllerAnimated(true)
}
}
You can also do it from Storyboard:
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("hideKeyboard"))
tapGesture.cancelsTouchesInView = true
tableView.addGestureRecognizer(tapGesture)
}
func hideKeyboard() {
tableView.endEditing(true)
}
Translating Objective-C code to Swift is not really hard. You just require a basic knowledge in both languages. If you're new to programming I guess you should familiarise with yourself with the basics first.
As #Ben already recommended, you can also do this programmatically.
Just put this in your viewDidLoad()
tableView.keyboardDismissMode = .onDrag
Swift 4:
On ViewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
self.yourTableView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:))))
}
On corresponding function:
#objc func handleTap(_ sender: UITapGestureRecognizer) {
if sender.state == .ended {
// Do your thang here!
self.view.endEditing(true)
for textField in self.view.subviews where textField is UITextField {
textField.resignFirstResponder()
}
}
sender.cancelsTouchesInView = false
}
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("hideKeyboard"))
tapGesture.cancelsTouchesInView = true
self.view.addGestureRecognizer(tapGesture)
}
func hideKeyboard()
{
self.view.endEditing(true)
}
this will work fine compared to the above which didnt work for me
For some reason, #Isuru's answer crashes in my app (XCode 7.2.1), and thankfully it's just a minor change - just remove the Selector() call:
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: "hideKeyboard")
tapGesture.cancelsTouchesInView = true
tableView.addGestureRecognizer(tapGesture)
}
func hideKeyboard() {
tableView.endEditing(true)
}
Accepted answer doesn't work for me on XCode 13.1, so I changed the code a little bit:
override func viewDidLoad() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.hideKeyboard))
tapGesture.cancelsTouchesInView = true
tableView.addGestureRecognizer(tapGesture)
}
#objc func hideKeyboard() {
tableView.endEditing(true)
}

How to move a image view down on swipe?

I have an image view and I needed the user swipe this image down but i don't know how to do this. I put a log to know if the swiping its working and its working well, i want that the image moves when I swipe. I'm very new in iOS. Can you help me??
Here is my ViewController class:
class MainScreenViewController: UIViewController {
#IBOutlet var buttonMenuEntry: UIButton
#IBOutlet var buttonMenuExit: UIButton
#IBOutlet var mainscreenEntryView: UIImageView
#IBOutlet var mainscreenCard: UIImageView
override func viewDidLoad() {
super.viewDidLoad()
var swipeCardDown = UISwipeGestureRecognizer(target: self, action: "respondToGesture:")
swipeCardDown.direction = UISwipeGestureRecognizerDirection.Down
self.mainscreenCard.addGestureRecognizer(swipeCardDown)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonMenuClicked(sender: UIButton){
buttonMenuEntry.hidden = true
buttonMenuExit.hidden = false
}
func respondToGesture(gesture: UIGestureRecognizer){
println("Swiped down")
}
}
Thanks.
Simplest way would be:
func respondToGesture(gesture: UIGestureRecognizer){
UIView.animateWithDuration(0.35, animations: {
mainscreenCard.frame = CGRectMake(mainscreenCard.frame.origin.x,
self.view.frame.height,
mainscreenCard.frame.size.width,
mainscreenCard.frame.size.height)
})
}
Adjust your timing as you wish

Resources