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
Related
import UIKit
class ViewController: UIViewController {
// #IBAction func Btndel(_ sender: Any) {
//}
var Str:String?
override func viewDidLoad() {
super.viewDidLoad()
let items = [Str]
let SegM = UISegmentedControl(items:items as Any as? [Any])
SegM.selectedSegmentIndex = 0
SegM.frame=CGRect(x: 70, y: 130, width: 100, height: 50)
SegM.layer.cornerRadius = 8.0
SegM.backgroundColor = .orange
SegM.tintColor = .white
self.view .addSubview(SegM)
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Btnadd(_ sender: Any)
{
var Str = 0;Str += 1
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
How to add and delete segments in a viewcontroller by clicking add button an delete button created in the same viewcontroller
How to insert and remove(add or delete) segments in swift4
class ViewController: UIViewController {
#IBOutlet weak var segment1: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func insert(_ sender: Any) {
segment1.insertSegment(withTitle: "\(segment1.numberOfSegments+1)", at: segment1.numberOfSegments, animated: true)
}
#IBAction func remove(_ sender: Any) {
segment1.removeSegment(at: segment1.numberOfSegments-1, animated: true)
}
}
You can insert segment by insertSegment method of UISegmentedControl and you can delete segment by removeSegment method. Let me take an example.
I create segmentController class and its UI in a storyboard.
Below is UI screenshot. In the storyboard, You can see two buttons Insert (+) and Remove (-) and UISegmentedControl. Insert button will insert segment at a specific position and Remove button will remove the segment at a specific position.
Below is code of segmentController class.
class segmentController: UIViewController {
#IBOutlet weak var segementControl: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func remove(_ sender: Any) {
segementControl.removeSegment(at: segementControl.numberOfSegments-1, animated: true)
}
#IBAction func insert(_ sender: Any) {
segementControl.insertSegment(withTitle: "\(segementControl.numberOfSegments+1)", at: segementControl.numberOfSegments, animated: true)
}
}
In the above code, on insert button click new segment will add at the last of segementControl. On remove button click the last segment will delete from segmentControl.
Hope it helps.
I want to trigger Navigation controller to some other screen when i press the button in UIView class. How can i do this?
//Code for UIView Class in Which Button Iboutlet is created
import UIKit
protocol ButtonDelegate: class {
func buttonTapped()
}
class SlidesVC: UIView {
var delegate: ButtonDelegate?
#IBAction func onClickFinish(_ sender: UIButton) {
delegate?.buttonTapped()
}
#IBOutlet weak var imgProfile: UIImageView!
}
//ViewController Class code in Which Button Protocol will be entertained
class SwipingMenuVC: BaseVC, UIScrollViewDelegate {
var slidesVC = SlidesVC()
override func viewDidLoad() {
super.viewDidLoad()
slidesVC = SlidesVC()
// add as subview, setup constraints etc
slidesVC.delegate = self
}
extension BaseVC: ButtonDelegate {
func buttonTapped() {
self.navigationController?.pushViewController(SettingsVC.settingsVC(),
animated: true)
}
}
A more easy way is to use typealias. You have to write code in 2 places. 1. your viewClass and 2. in your View Controller.
in your SlidesView class add a typealias and define param type if you need otherwise leave it empty.
class SlidesView: UIView {
typealias OnTapInviteContact = () -> Void
var onTapinviteContact: OnTapInviteContact?
#IBAction func buttonWasTapped(_ sender: UIButton) {
if self.onTapinviteContact != nil {
self.onTapinviteContact()
}
}
}
class SwipingMenuVC: BaseVC, UIScrollViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let slidesView = SlidesView()
slidesView.onTapinviteContact = { () in
// do whatever you want to do on button tap
}
}
You can use the delegate pattern to tell the containing ViewController that the button was pressed and let it handle whatever is needed to do next, The view doesn't really need to know what happens.
A basic example:
protocol ButtonDelegate: class {
func buttonTapped()
}
class SomeView: UIView {
var delegate: ButtonDelegate?
#IBAction func buttonWasTapped(_ sender: UIButton) {
delegate?.buttonTapped()
}
}
class ViewController: UIViewController {
var someView: SomeView
override func viewDidLoad() {
someView = SomeView()
// add as subview, setup constraints etc
someView.delegate = self
}
}
extension ViewController: ButtonDelegate {
func buttonTapped() {
self.showSomeOtherViewController()
// or
let vc = NewViewController()
present(vc, animated: true)
}
}
Hi i'm new with Swift programming.
What im trying to do is Disable my button (signIn) in viewDidLoad and only enable when the textfields have text in them. Here's what i've achieved so far. (not much though!)
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
signIn.isEnabled = false
// Do any additional setup after loading the view, typically from a nib.
}
#IBOutlet weak var emailtxt: UITextField!
#IBOutlet weak var passwordtxt: UITextField!
#IBOutlet weak var signIn: UIButton!
I need help to create a function in signIn that keeps button disabled until text fields (emailtxt & passwordtxt) have text in them and then proceed.
Glad if anyone can sort me.
Thanks in advance!
First add these for all of your textFields in viewDidLoad():
emailtxt.addTarget(self, action: #selector(textFieldDidChange(_:)),
for: UIControlEvents.editingChanged)
passwordtxt.addTarget(self, action: #selector(textFieldDidChange(_:)),
for: UIControlEvents.editingChanged)
Then use this:
#objc func textFieldDidChange(_ textField: UITextField) {
self.buttonIsEnabled()
}
func buttonIsEnabled() {
var buttonIsEnabled = true
defer {
self.signIn.isEnabled = buttonIsEnabled
}
guard let emailtxt = self.emailtxt.text, !emailtxt.isEmpty else {
addButtonIsEnabled = false
return
}
guard let passwordtxt = self. passwordtxt.text, ! passwordtxt.isEmpty else {
addButtonIsEnabled = false
return
}
}
I use this way in my codes and it works well.
Even you can add more methods for additional checking to buttonIsEnabled, like:
self.checkEmailIsValid(for: emailtxt)
Of course you should handle this method before:
func checkEmailIsValid(for: String) {
//...
}
Set ViewController as delegate for emailtxt and passwordtxt like this,
override func viewDidLoad() {
super.viewDidLoad()
signIn.isEnabled = false
emailtxt.delegate = self
passwordtxt.delegate = self
// Do any additional setup after loading the view, typically from a nib.
}
Conform your ViewController to UITextFieldDelegate and enable/disable as the text input is finished,
extension ViewController: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
if emailtxt.text?.isEmpty == false && passwordtxt.text?.isEmpty == false {
signIn.isEnabled = true
} else {
signIn.isEnabled = false
}
}
}
Here is the fix for your code you shared.
import UIKit
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
extension SignInVC: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
if emailtxt.text?.isEmpty == false && passwordtxt.text?.isEmpty == false {
signIn.isEnabled = true
} else {
signIn.isEnabled = false
}
}
}
class SignInVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
signIn.isEnabled = false
emailtxt.delegate = self
passwordtxt.delegate = self
self.hideKeyboardWhenTappedAround()
// 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.
}
#IBOutlet weak var emailtxt: UITextField!
#IBOutlet weak var passwordtxt: UITextField!
#IBOutlet weak var signIn: UIButton!
}
What I would do is create an IBAction from one of your text fields, and set the event to Editing Changed:
The code should look like this:
#IBAction func textFieldEditingDidChange(_ sender: UITextField) {
}
You can then connect that same outlet to both of your text fields by dragging from the outlet to your remaining field. If you've connected both correctly, clicking on the circle to the left of your IBAction should show two text fields:
The action will now be fired every time text changes in either of your fields.
Then, at the top of the file, I'd create a computed property that returns false unless there is something in both fields:
var shouldEnableButton: Bool {
guard let text1 = textField1.text, let text2 = textField2.text else {
return false
}
return text1.isEmpty && text2.isEmpty ? false : true
}
Finally, we add shouldEnableButton to our IBAction:
#IBAction func textFieldEditingDidChange(_ sender: UITextField) {
button.isEnabled = shouldEnableButton
}
Important
When you connect your second text field to the outlet, it will incorrectly assign Editing Did End as its event:
Delete this event and click and drag from Editing Changed to your IBAction:
Use SwiftValidator
https://github.com/SwiftValidatorCommunity/SwiftValidator
by this, you will set validation of email & password like below
import SwiftValidator
let validator = Validator()
validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule(message: "Invalid email")])
// MARK: - ValidationDelegate
extension ViewController: ValidationDelegate {
func validationSuccessful() {
self.loginUser()
}
func validationFailed(_ errors:[(Validatable ,ValidationError)]) {
for (field, error) in errors {
//Handle as per need - show extra label - shake view etc
/*
if let field = field as? UITextField {
Utilities.shakeTheView(shakeView: field)
}
error.errorLabel?.text = error.errorMessage
error.errorLabel?.isHidden = false
*/
}
}
}
i'm a beginner in swift and i have been using this dismissKeyboard() method but it is not working for the keyboard extension.
#IBAction func donePressed (sender: UIButton) {
dismissKeyboard()
}
can anyone tell me why this doesn't work?
thanks.
EDIT: full code
import UIKit
class KeyboardViewController: UIInputViewController {
var keyboardView: UIView!
#IBOutlet var nextKeyboardButton: UIButton!
override func updateViewConstraints() {
super.updateViewConstraints()
// Add custom view sizing constraints here
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadInterface()
}
func loadInterface() {
var keyboardNib = UINib(nibName: "KeyboardView", bundle: nil)
self.keyboardView = keyboardNib.instantiateWithOwner(self, options: nil)[0] as UIView
view.addSubview(self.keyboardView)
view.backgroundColor = self.keyboardView.backgroundColor
self.nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)
self.nextKeyboardButton.addTarget(self, action: "advanceToNextInputMode", forControlEvents: .TouchUpInside)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated
}
override func textWillChange(textInput: UITextInput) {
// The app is about to change the document's contents. Perform any preparation here.
}
override func textDidChange(textInput: UITextInput) {
// The app has just changed the document's contents, the document context has been updated.
}
#IBAction func buttonPressed (sender: UIButton) {
let title = sender.titleForState(.Normal)
var proxy = textDocumentProxy as UITextDocumentProxy
proxy.insertText(title!)
}
#IBAction func spacePressed (sender: UIButton) {
var proxy = textDocumentProxy as UITextDocumentProxy
proxy.insertText(" ")
}
#IBAction func deletePressed (sender: UIButton) {
var proxy = textDocumentProxy as UITextDocumentProxy
proxy.deleteBackward()
}
#IBAction func donePressed (sender: UIButton) {
resignFirstResponder()
}
}
Try like that
self.dismissKeyboard()
Maybe try :
view.endEditing(true)
Dismisses the custom keyboard from the screen.
Swift:
self.dismissKeyboard()
Objective-C:
[self dismissKeyboard];
https://developer.apple.com/documentation/uikit/uiinputviewcontroller/1618196-dismisskeyboard?language=objc
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