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
Related
I am playing with ProgressView. What I want to achieve is stopping at 33%, 66%, 100% checkpoints on button click. It's working okay if I use progressView.progress = 0.33, but it directly lands to the checkpoint. Instead, having it smooth and accelerating would look so nice.
I thought animateWithDuration would work but unfortunately it doesn't. After some reading, I found out that I can do something with NSTimer, but I couldn't achieve it.
var progressView: UIProgressView?
override func viewDidLoad()
{
super.viewDidLoad()
progressView = UIProgressView(progressViewStyle: UIProgressViewStyle.Default)
progressView?.center = self.view.center
progressView?.trackTintColor = UIColor.redColor()
progressView?.progressTintColor = UIColor.greenColor()
view.addSubview(progressView!)
progressView!.progress = 0.0
}
Using this answer, I achieved making it move once in every second, but how can I make it go smooth, slow in the beginning and accelerating, so looks nice.
using setProgress method and setting animation to true makes animation work.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var pb: UIProgressView!
#IBOutlet weak var btn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
pb.progress = 0.00
}
#IBAction func btnPress(sender: UIButton) {
UIView.animateWithDuration(3, animations: {
self.pb.setProgress((self.pb.progress + 0.33), animated: true)
}, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
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 :)
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
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
I set one UILongPressGestureRecognizer to handle four different buttons in my view, how do I access which button is being clicked in my code?
My UILongPressGestureRecognizer looks like it:
#IBAction func editText(sender: UILongPressGestureRecognizer) {
textFieldInput.hidden = false
iphoneSaveCharName.hidden = false
}
And I Want to use Long Press so that I can edit the button text
EDIT 1:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var iphoneTableView: UITableView!
#IBOutlet weak var textFieldInput: UITextField!
#IBOutlet weak var iphoneSaveCharName: UIButton!
#IBOutlet weak var charOne: UILabel!
#IBOutlet weak var charTwo: UILabel!
#IBOutlet weak var charTree: UILabel!
#IBOutlet weak var charFour: UILabel!
#IBOutlet weak var test1: UIButton! //button that I am clicking on!
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.
}
//Function I made so I can save the user input
#IBAction func iphoneSaveTextInput(sender: UIButton) {
let textData = textFieldInput.text
textFieldInput.hidden = true
iphoneSaveCharName.hidden = true
charTwo.text = textData
}
// This is the LongPress Action
#IBAction func editText(sender: UILongPressGestureRecognizer) {
textFieldInput.hidden = false
iphoneSaveCharName.hidden = false
func longPressMethod(gesture: UILongPressGestureRecognizer) {
println(gesture.view)
if gesture.view is UIButton {
let test1 = gesture.view as UIButton
println(test1)
}
}
}
}
Edit 2: Layout
Edit 3: New ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var iphoneTableView: UITableView!
#IBOutlet weak var textFieldInput: UITextField!
#IBOutlet weak var iphoneSaveCharName: UIButton!
#IBOutlet weak var charOne: UIButton!
#IBOutlet weak var charTwo: UIButton!
#IBOutlet weak var charThree: UIButton!
#IBOutlet weak var charFour: UIButton!
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 iphoneSaveTextInput(sender: UIButton) -> Void{
let textData = textFieldInput.text
textFieldInput.hidden = true
iphoneSaveCharName.hidden = true
}
#IBAction func editText(sender: AnyObject) {
if sender is UILongPressGestureRecognizer &&
sender.state == UIGestureRecognizerState.Began {
textFieldInput.hidden = false
iphoneSaveCharName.hidden = false
// func iphoneSaveTextInput(sender: UIButton){
// var textData = textFieldInput.text
// textFieldInput.hidden = true
// iphoneSaveCharName.hidden = true
//
// }
let button = sender.view as UIButton
println(button)
if button.tag == 1{
charOne.setTitle("textData", forState: .Normal)
} else if button.tag == 2{
charTwo.setTitle("textData2", forState: .Normal)
} else if button.tag == 3{
charThree.setTitle("textData3", forState: .Normal)
} else if button.tag == 4{
charFour.setTitle("textData4", forState: .Normal)
}
}
}
}
Answer:
This is the final view control:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var iphoneTableView: UITableView!
#IBOutlet weak var textFieldInput: UITextField!
#IBOutlet weak var iphoneSaveCharName: UIButton!
#IBOutlet weak var charOne: UIButton!
#IBOutlet weak var charTwo: UIButton!
#IBOutlet weak var charThree: UIButton!
#IBOutlet weak var charFour: UIButton!
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 iphoneSaveTextInput(sender: UIButton) -> Void{
let textData = textFieldInput.text
textFieldInput.hidden = true
iphoneSaveCharName.hidden = true
}
#IBAction func editText(sender: AnyObject) {
if sender is UILongPressGestureRecognizer &&
sender.state == UIGestureRecognizerState.Began {
textFieldInput.hidden = false
iphoneSaveCharName.hidden = false
// func iphoneSaveTextInput(sender: UIButton){
// var textData = textFieldInput.text
// textFieldInput.hidden = true
// iphoneSaveCharName.hidden = true
//
// }
let button = sender.view as UIButton
println(button)
if button.tag == 1{
charOne.setTitle("textData", forState: .Normal)
} else if button.tag == 2{
charTwo.setTitle("textData2", forState: .Normal)
} else if button.tag == 3{
charThree.setTitle("textData3", forState: .Normal)
} else if button.tag == 4{
charFour.setTitle("textData4", forState: .Normal)
}
}
}
}
I would mostly like to give you all a best answer since everybody helped me out! I had to create one Long Press for each button, otherwise code will get confused.
Your question has introduced me to a really cool feature, so thanks! :)
It turns out that if you attach a UILongPressGestureRecognizer to a UIButton in a storyboard and attach that button and gesture to an IBAction within your swift class, that IBAction method can recognize whether the touch is a tap or long press! Pretty cool, huh?
So first off, make sure that each UIButton has its own unique UILongPressGestureRecognizer; then you can edit your code like so, so that it's able to identify which button is being pressed and whether that press is either a simple tap or UILongPressGestureRecognizer:
// Connect both your button *and* its gestures to the
// `IBAction` method so that the function will be called
// no matter what kind of gesture it recognizes -- tap,
// long press, or otherwise.
#IBAction func buttonSelected(sender: AnyObject) {
// But to see if the gesture is a long press, you can
// simply check the sender's class and execute the code
// when the gesture begins.
if sender is UILongPressGestureRecognizer &&
sender.state == UIGestureRecognizerState.Began {
// These two lines are originally from your
// editText method
textFieldInput.hidden = false
iphoneSaveCharName.hidden = false
// Then to identify which button was long pressed you
// can check the sender's view, to see which button IBOutlet
// that gesture's view belongs to.
// Method #1:
let button = sender.view as UIButton
if button == thisButton {
} else if button == thatButton {
}
...
// Or you can check the gesture view's tag to see which
// button it belongs to (i.e. whichever button has a matching
// tag).
// Method #2:
let button = sender.view as UIButton
if button.tag == 1 {
} else if button.tag == 2 {
}
...
}
// Else if it's not a long press gesture, perform
// whatever action you'd like to accomplish during a
// normal button tap
else if !(sender is UILongPressGestureRecognizer) {
// These lines are originally from your
// iphoneSaveTextInput
let textData = textFieldInput.text
textFieldInput.hidden = true
iphoneSaveCharName.hidden = true
}
}
But if you want to continue to keep the UILongPressGestureRecognizer IBAction separate from the UIButton's IBAction (i.e. link the UIButtons to iphoneSaveTextInput: and your UILongPressGestureRecognizers to editText:), that should be OK too. Just keep your iphoneSaveTextInput: method as is, and update your editText: method like so:
// This is the LongPress Action
#IBAction func editText(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Began {
textFieldInput.hidden = false
iphoneSaveCharName.hidden = false
// Then to identify which button was long pressed you
// can check the sender's view, to see which button IBOutlet
// that gesture's view belongs to.
// Method #1:
let button = sender.view as UIButton
if button == thisButton {
} else if button == thatButton {
}
...
// Or you can check the gesture view's tag to see which
// button it belongs to (i.e. whichever button has a matching
// tag).
// Method #2:
let button = sender.view as UIButton
if button.tag == 1 {
} else if button.tag == 2 {
}
...
}
}
You don't want to use the same gesture recognizer across different views:
Can you attach a UIGestureRecognizer to multiple views?
The view property of the gesture recognizer is probably what you would want to check but you want different gesture recognizers for each view.
If you want, they could all be linked to the same selector, though, and you could access the incoming recognizer's view that way.
A general way to make a button have different actions based on how long you press it, looks like this (timer is a property),
#IBAction func buttonDown(sender: UIButton) { // connected to touchDown
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "handleTimer", userInfo: sender, repeats: false)
}
#IBAction func buttonUp(sender: UIButton) { // connected to touchUpInside
if timer != nil {
timer.invalidate()
println("change view")
}
}
func handleTimer() {
var button = timer.userInfo as UIButton
timer = nil
button.setTitle("New Title", forState: .Normal)
}