I need to know when the cancel button of the UISearchBar has finished his animation after calling
searchBar.setShowsCancelButton(false, animated: true)
I've tried this
UIView.animateWithDuration(3, animations: {
self.searchBarView.searchBar.showsCancelButton = false
}, completion: {finished in
print(finished)
})
but the completion block gets triggered immediatly, any solution would be appreciated
You can use layoutIfNeeded() to update view in UIView.animateWithDuration(...)
try this code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var searchBar: UISearchBar!
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 touchUpInside(sender: UIButton) {
searchBar.showsCancelButton = !searchBar.showsCancelButton
UIView.animateWithDuration(3, animations: {
self.searchBar.layoutIfNeeded()
}, completion: {finished in
print("Animation finished")
})
}
}
and storyboard:
Related
I am trying to create a drop down menu, that when you press the "Select" button two options drop down. I want these options to be a Timesheet button and Expense report button. I can't get it to work, here is my code.
import UIKit
class SecondViewController: UIViewController {
#IBOutlet weak var SelectBTN: 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 handleSelection(_ sender: UIButton) {
SelectBTN.ForEach { (button) in
UIView.animate(withDuration: 0.3, animations: {
button.isHidden = !button.isHidden
self.view.layoutIfNeeded()
})
}
}
#IBAction func cityTapped(_ sender: UIButton) {
}
#IBAction func ERBTNpressed(_ sender: UIButton) {
self.performSegue(withIdentifier: "ERSegue", sender: self)
}
#IBAction func TSBTNpressed(_ sender: UIButton) {
self.performSegue(withIdentifier: "TSSegue", sender: self)
}
}
You could set a menu as a primary action for a button in viewDidLoad:
SelectBTN.showsMenuAsPrimaryAction = true
SelectBTN.menu = buttonMenu()
In the menu you could add actions:
func buttonMenu() -> UIMenu {
let ERAction = UIAction(title: "Expense report", image: nil) { (_) in
self.performSegue(withIdentifier: "ERSegue", sender: self)
}
let TSAction = UIAction(title: "Timesheet", image: nil) { (_) in
self.performSegue(withIdentifier: "TSSegue", sender: self)
}
return UIMenu(title: "", options: .displayInline, children: [ERAction, TSAction])
}
You could also add images to actions and specify attributes (i.e. .destructive for Delete action)
On my mainVC I have a TableView with a button that should open the secondVC, where I can add things to show then in the Table, with the kind: "Present As Popover".
I'm opening the secondVC with performSegue(withIdentifier:"goToOtherView", sender: nil.
class FirstViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var groupData = ["Data, Data1, Data2"]
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
tableView.delegate = self
tableView.dataSource = self
}
#IBAction func btnTapped(_ sender: Any) {
performSegue(withIdentifier: "goToOtherView", sender: nil)
}
override func viewWillAppear(_ animated: Bool) {
print("FirstViewController will appear")
}
override func viewDidAppear(_ animated: Bool) {
print("FirstViewController did appear")
}
override func viewWillDisappear(_ animated: Bool) {
print("FirstViewController will disappear")
}
override func viewDidDisappear(_ animated: Bool) {
print("FirstViewController did disappear")
}
}
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .blue
}
override func viewWillAppear(_ animated: Bool) {
print("SecoundViewController will appear")
}
override func viewDidAppear(_ animated: Bool) {
print("SecoundViewController did appear")
}
override func viewWillDisappear(_ animated: Bool) {
print("SecoundViewController will disappear")
}
override func viewDidDisappear(_ animated: Bool) {
print("SecoundViewController did disappear")
}
}
Storyboard
When I start the App
When I open the secondVC
And when I close the secondVC
The FirstViewController willDisappear and didDisappear are never being called, or even when the secondVC is closed the willAppear and didAppear. I want to call the function tableView.reloadData() when the FirstView willAppear/didAppear
It's kinda the same like the IOS default clock app, when you add a new alarm clock.
Quick guess, but I think that’s because of the presentation mode being pageSheet
Can you try to change it to fullScreen?
You can also change your segue configuration to be like:
View disappear won't be called since the view does not completely disappears from the window
I am working in a form in swift 3, my problem is when I tried to hide the keyboard in textview because the keyboard reuse to hide and is still visible in the previous VC.
My question is what I missing to fix this and when tap outside of textview the keyboard hide automatically?
Here the code:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return(true)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if(textField == names){
scrooView.setContentOffset(CGPoint(x:0, y:250), animated: true)
}
else if(textField == email){
scrooView.setContentOffset(CGPoint(x:0, y:250), animated: true)
}
else if (textField == tel){
scrooView.setContentOffset(CGPoint(x:0, y:250), animated: true)
}
else if (textField == message){
scrooView.setContentOffset(CGPoint(x:0, y:450), animated: true)
}
}
func textFieldDidEndEditing(_ textField: UITextField, reason:
UITextFieldDidEndEditingReason) {
scrooView.setContentOffset(CGPoint(x:0, y:0), animated: true)
}
extension UIViewController{
func hideKeyboard(){
let tap: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(UIViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard(){
view.endEditing(true)
}
}
Here a link with the issue!
You are using a scrollView, try to add the GestureRecognizer in them, like this:
class ViewController: UIViewController {
#IBOutlet weak var scrooView: UIScrollView!
#IBOutlet weak var tfTest: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
scrooView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)))
// 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.
}
#objc func dismissKeyboard(){
tfTest.endEditing(true)
}
})
If you add your Gesture in your View, it could never actived 'cause you are touching the scrollview that is over the view.
The cancel button on right top corner after a message composer has been presented is not visible in iOS 11 devices. As shown in the screenshot, cancel button works but is not visible. Once we press on it, the screen dismisses.
I have tried like this:
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate {
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 Messages(_ sender: UIButton) {
if MFMessageComposeViewController.canSendText() == true {
let recipients:[String] = ["1500"]
let messageController = MFMessageComposeViewController()
messageController.messageComposeDelegate = self
messageController.recipients = recipients
messageController.body = "Your_text"
self.present(messageController, animated: true, completion: nil)
} else {
//handle text messaging not available
}
}
func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
controller.dismiss(animated: true, completion: nil)
}
}
Added Messages and MessageUI frameworks and imported in view controller.
Screenshot:
Image:
The cancel button only clears the recipient phone number but does not go back to the app? Any help? Here is the code I'm currently using.....
import UIKit
import MessageUI
class ViewController: UIViewController, MFMessageComposeViewControllerDelegate {
#IBOutlet weak var txtMsg: UITextField!
#IBOutlet weak var txtPhone: UITextField!
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 sndSMS(sender: AnyObject) {
txtMsg.resignFirstResponder()
txtPhone.resignFirstResponder()
let msgVC = MFMessageComposeViewController()
msgVC.body = txtMsg.text!
msgVC.recipients = ["1-206-724-8288"]
msgVC.messageComposeDelegate = self;
self.presentViewController(msgVC, animated: true, completion: nil)
You're assigning the delegate but you are not implementing the method listed here:
https://developer.apple.com/documentation/messageui/mfmessagecomposeviewcontrollerdelegate/1614061-messagecomposeviewcontroller
func messageComposeViewController(_ controller: MFMessageComposeViewController,
didFinishWithResult result: MessageComposeResult)