update UIViewController in Real Time from Popover Viewcontroller in Swift 4 - swift

right now i'm experimenting with SceneKit DebugOptions.
i'm trying to update/ show Scenekits Debug Options in real time, using switch controllers from a Popover ViewController.
i've tried many things, like UserDefaults, Delegation and Protocols, but stil i wasn't able to see the result in real time, every time i have to kill the app en relaunch it to see the results.
so, i would be greatfull if someone would have an answer to my question :D
extension i added to my MainVC
extension ViewController: UIPopoverPresentationControllerDelegate, DebugOptions {
func wireFrameEnabled(enabled: Bool) {
if enabled == true {
print(enabled)
}
}
func showCameraEnabled(enabled: Bool) {
}
func showAllDebugOptions(enabled: Bool) {
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let popoverController = segue.destination.popoverPresentationController, let button = sender as? UIButton else { return }
popoverController.delegate = self
popoverController.sourceRect = button.bounds
let debugMenuVC = popoverController.presentedViewController as! DebugMenuVC
debugMenuVC.delegate? = self
}
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}
}
Protocol
protocol DebugOptions {
func wireFrameEnabled(enabled: Bool)
func showCameraEnabled(enabled: Bool)
func showAllDebugOptions(enabled: Bool)
}
DebugMenuVC
class DebugMenuVC: UIViewController {
#IBOutlet weak var bgView: UIView!
#IBOutlet weak var showWireFrameSwitch: UISwitch!
#IBOutlet weak var showCameraSwitch: UISwitch!
#IBOutlet weak var showAllSwitch: UISwitch!
var delegate: DebugOptions?
override func viewWillLayoutSubviews() {
preferredContentSize = CGSize(width: 150, height: 300)
}
override func viewDidLoad() {
super.viewDidLoad()
buttonCheck()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
#IBAction func aSwitchBtnWasPressed( _ sender: UISwitch ) {
if (sender.tag == 0) && (sender.isOn == true) {
userDefaults.set(true, forKey: SHOW_WIRE_FRAME)
delegate?.wireFrameEnabled(enabled: true)
} else if (sender.tag == 0) && (sender.isOn == false) {
userDefaults.set(false, forKey: SHOW_WIRE_FRAME)
delegate?.wireFrameEnabled(enabled: false)
}
}
func buttonCheck() {
if userDefaults.bool(forKey: SHOW_WIRE_FRAME) == true{
showWireFrameSwitch.isOn = true
} else {
showWireFrameSwitch.isOn = false
}
}
}

in debubMenuVC.delegate shouldn't be an optional. thats the reason the delegation method always failed :D
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let popoverController = segue.destination.popoverPresentationController, let button = sender as? UIButton else { return }
popoverController.delegate = self
popoverController.sourceRect = button.bounds
let debugMenuVC = popoverController.presentedViewController as! DebugMenuVC
debugMenuVC.delegate? = self
}

Related

ViewController doesn't pass data on completion

I have 2 ViewControllers.
TimerViewController passes a variable to the EditTimerViewConroller. EditTimerViewConroller edits it and should pass it back, but it looks like code in .completion is not executed.
Any advice how to fix it?
My code is:
TimerViewController
import UIKit
import AVFoundation //play sounds
class TimerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var player: AVAudioPlayer!
var timer = Timer()
var totalTime = 10.0
var secondsRemaining = 10.0
var secondsPassed = 0.0
let timerStep = 0.1
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var progressBar: UIProgressView!
#IBAction func startPressed(_ sender: UIButton) {
//works fine
}
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
let editTimer = EditTimerViewController()
editTimer.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \(self?.totalTime)")
}
}
}
func playSound(fileName: String) {
//works fine
}
#objc func updateTimer() {
//works fine
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(totalTime)
print("Pasing duration = \(totalTime) to Edit screen")
}
}
EditTimerViewController
import UIKit
class EditTimerViewController: UIViewController {
let maxDuration = 60
var duration: Int? //timer duraton is passed from Timer
public var completion: ((Int?) -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
durationSlider.minimumValue = 0
durationSlider.maximumValue = Float(maxDuration)
durationSlider.value = Float(duration!)
durationLabel.text = String(duration!) + "s"
}
#IBOutlet weak var durationLabel: UILabel!
#IBOutlet weak var durationSlider: UISlider!
#IBAction func durationSliderChanged(_ sender: UISlider) {
duration = Int(sender.value)
print(duration!)
durationLabel.text = String(duration!) + "s"
}
#IBAction func cancelPressed(_ sender: UIButton) {
print("Cancel pressed, dismissing Edit screen")
self.dismiss(animated: true, completion: nil)
}
#IBAction func savePressed(_ sender: UIButton) {
print("Save pressed, duration is \(duration!)")
completion?(duration!)
self.dismiss(animated: true, completion: nil)
}
}
In the output after pressing Save button I see
Save pressed, duration is 11
but after it there is no sign of
editTimer completed, totalTime now is 11
and timer duration never changes
Change
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
let editTimer = EditTimerViewController()
editTimer.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \(self?.totalTime)")
}
}
}
To
#IBAction func editTimerButtinPresed(_ sender: UIButton) {
self.performSegue(withIdentifier: "goToEditTimer", sender: self)
}
And move completion inside prepare
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditTimer" {
let destinationVC = segue.destination as! EditTimerViewController
destinationVC.duration = Int(totalTime)
print("Pasing duration = \(totalTime) to Edit screen")
destinationVC.completion = { [weak self] duration in
DispatchQueue.main.async {
self?.totalTime = Double(duration!)
print("editTimer completed, totalTime now is \ (self?.totalTime)")
}
}
}
}

Sending a string from one viewcontroller to another using delegate in swift

I'm trying to make a button click in PopupViewController fill a textfield in DagbogsindlaegViewController with a string "svimmelhed, ".
I'm not getting any errors when running the code, but the text is not there when i run the app simulation and press "ButtonPressSvimmelhed" in the class PopupViewController.
Is there a kind stranger who can help me and tell me what i am doing wrong?
Code below:
import UIKit
import EventKit
class DagbogsindlaegViewController: UIViewController{
#IBAction func BackToSVC(_ sender: Any){
self.performSegue(withIdentifier: "BackToSVCSegue", sender: self)
}
#IBAction func ToCalenderButtonPress(_ sender: Any) {
self.performSegue(withIdentifier: "ToCalenderSegue", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
TitleTextField.delegate = self
DescriptionTextField.delegate = self
// Do any additional setup after loading the view.
}
#IBOutlet weak var TitleTextField: UITextField!
#IBOutlet weak var DescriptionTextField: UITextField!
func addEventToCalendar(title: String, description: String?, startDate: Date, endDate: Date, completion: ((_ success: Bool, _ error: NSError?) -> Void)? = nil) {
let eventStore = EKEventStore()
eventStore.requestAccess(to: .event, completion: { (granted, error) in
if (granted) && (error == nil) {
let event = EKEvent(eventStore: eventStore)
event.title = title
event.startDate = startDate
event.endDate = endDate
event.notes = description
event.calendar = eventStore.defaultCalendarForNewEvents
do {
try eventStore.save(event, span: .thisEvent)
} catch let e as NSError {
completion?(false, e)
return
}
completion?(true, nil)
} else {
completion?(false, error as NSError?)
}
})
}
#IBAction func ButtonPressGemDagbog(_ sender: Any) {
addEventToCalendar(title: "\(String(describing: TitleTextField.text!))", description: "\(String(describing: DescriptionTextField.text!))", startDate: NSDate() as Date, endDate: NSDate() as Date)
}
#IBAction func ButtonPressPopupMenu(_ sender: Any) {
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PopupViewControllerID") as! PopupViewController
self.addChild(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParent: self)
}
}
extension DagbogsindlaegViewController : UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
extension DagbogsindlaegViewController : TextFraPopupDelegate {
func Symptomer(Svimmelhed: String) {
TitleTextField.text = Svimmelhed
}
}
And the other view controller:
import UIKit
protocol TextFraPopupDelegate{
func Symptomer(Svimmelhed: String)
}
class PopupViewController: UIViewController {
var symptomDelegate: TextFraPopupDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.showAnimate()
self.view.backgroundColor = UIColor.black.withAlphaComponent(0.8)
// Do any additional setup after loading the view.
}
#IBAction func ButtonPressBackToDagbogsindlaeg(_ sender: Any) {
self.removeAnimate()
//self.view.removeFromSuperview()
}
func showAnimate()
{
self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.view.alpha = 0.0;
UIView.animate(withDuration: 0.25, animations: {
self.view.alpha = 1.0
self.view.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
});
}
func removeAnimate()
{
UIView.animate(withDuration: 0.25, animations: {
self.view.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
self.view.alpha = 0.0;
}, completion:{(finished : Bool) in
if (finished)
{
self.view.removeFromSuperview()
}
});
}
#IBAction func ButtonPressSvimmelhed(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
} else {
sender.isSelected = true
}
symptomDelegate?.Symptomer(Svimmelhed: "Svimmelhed, ")
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
}
As mentioned in the comments the delegate is not set.
However in Swift there is a more convenient way to pass the string back to the presenting view controller, a callback closure. You get rid of the protocol and of the duty to set the delegate
Delete
protocol TextFraPopupDelegate{
func Symptomer(Svimmelhed: String)
}
In PopupViewController replace
var symptomDelegate: TextFraPopupDelegate?
with
var callback : ((String) -> Void)?
and
#IBAction func ButtonPressSvimmelhed(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
} else {
sender.isSelected = true
}
symptomDelegate?.Symptomer(Svimmelhed: "Svimmelhed, ")
}
with
#IBAction func ButtonPressSvimmelhed(_ sender: UIButton) {
sender.isSelected.toggle()
callback?("Svimmelhed, ")
}
In DagbogsindlaegViewController in ButtonPressPopupMenu add the closure
#IBAction func ButtonPressPopupMenu(_ sender: Any) {
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PopupViewControllerID") as! PopupViewController
self.addChild(popOverVC)
popOverVC.view.frame = self.view.frame
popOverVC.callback = { string in
self.TitleTextField.text = string
}
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParent: self)
}
Finally delete
extension DagbogsindlaegViewController : TextFraPopupDelegate {
func Symptomer(Svimmelhed: String) {
TitleTextField.text = Svimmelhed
}
}
Notes:
The syntax (_ success: Bool, _ error: NSError?) -> Void)? is outdated. Since Swift 3 the parameter labels are gone, this is sufficient: (Bool, NSError?) -> Void)?
Don't use NS... classes in Swift if there are native counterparts for example Date
Please conform to the naming convention to name variables and functions / methods with a starting lowercase letter.
The syntax "\(String(describing: TitleTextField.text!))" is double redundant. You create a string from a string from a string. Replace it with TitleTextField.text!

How to pass different URL to webView from some buttons in swift?

I have some buttons in first view controller and a webView in second view controller. How to pass different url from different buttons to the webView? For example, the first button will leads to a google website and the second one is Facebook but using the same webView. Do I need to create different segues for each button or just one? If using just one, where should I start pulling that blue line (that line when you hold the control key)?
In first viewController:
class CafesView: UIViewController {
#IBOutlet weak var topBar: UIView!
#IBOutlet weak var button1: MDCFloatingButton!
#IBOutlet weak var button2: MDCRaisedButton!
#IBOutlet weak var button3: MDCRaisedButton!
#IBOutlet weak var button4: MDCRaisedButton!
#IBOutlet weak var button5: MDCRaisedButton!
#IBOutlet weak var button6: MDCRaisedButton!
#IBOutlet weak var button7: MDCRaisedButton!
#IBOutlet weak var button8: MDCRaisedButton!
#IBOutlet weak var button9: MDCRaisedButton!
let cafes = [
"Banana Joe's",
"College Eight Cafe",
"Global Village",
"Iveta",
"Oakes Cafe",
"Perk Coffee Bar",
"Stevenson Coffee House",
"Terra Fresca",
"Vivas"
]
var urlToPass: String!
override func viewDidLoad() {
super.viewDidLoad()
topBar.layer.shadowColor = UIColor.black.cgColor
topBar.layer.shadowOpacity = 0.5
topBar.layer.shadowOffset = CGSize(width: 0, height: 2)
topBar.layer.shadowRadius = 5
button1.layer.cornerRadius = 20
button2.layer.cornerRadius = 20
button3.layer.cornerRadius = 20
button4.layer.cornerRadius = 20
button5.layer.cornerRadius = 20
button6.layer.cornerRadius = 20
button7.layer.cornerRadius = 20
button8.layer.cornerRadius = 20
button9.layer.cornerRadius = 20
}
#IBAction func bananaJoes(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/banana-joes-menu.pdf"
}
#IBAction func collegeEightCafe(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/c8-menu.pdf"
}
#IBAction func globalVillage(_ sender: Any) {
urlToPass = "https://www.foodbooking.com/ordering/restaurant/menu?restaurant_uid=d368abee-3ccc-40d7-be7f-3ca5d4cbd513&glfa_cid=1263531392.1571083521&glfa_t=1571083566919"
}
#IBAction func iveta(_ sender: UIButton) {
urlToPass = "https://iveta.com/pages/iveta-ucsc-menu"
}
#IBAction func oakesCafe(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/oakes-menu-2019-20.pdf"
}
#IBAction func perkCoffeeBar(_ sender: UIButton) {
urlToPass = "https://google.com" //This url is just a placeholder
}
#IBAction func stevensonCoffeeHouse(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/stevenson-coffee-house-menu.pdf"
}
#IBAction func terraFresca(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/terra-fresca/pdf/terra-fresca-menu.pdf"
}
#IBAction func vivas(_ sender: UIButton) {
urlToPass = "https://dining.ucsc.edu/pdf/vivas-menu.pdf"
}
#IBAction func dismiss(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let destination = segue.destination as? CafesMenu else { return }
destination.detailURL = urlToPass
urlToPass = nil
}
}
In the second one:
import UIKit
import WebKit
class CafesMenu: UIViewController {
#IBOutlet weak var webView: WKWebView!
var detailURL: String?
override func viewDidLoad() {
super.viewDidLoad()
print("URL Requested: \(detailURL)")
}
override func viewWillAppear(_ animated: Bool) {
let url = URL(string: detailURL!)
let request = URLRequest(url: url!)
webView.load(request)
}
#IBAction func dismiss(_ sender: UIBarButtonItem) {
self.dismiss(animated: true, completion: nil)
}
}
What you need to do is use prepareForSegue:sender: to set a property in your destination view controller. prepareForSegue:sender: will be called before your initial view controller segues to any destination view controller. Within this function, we can check which button was pressed and set the appropriate URL in the destination view controller accordingly.
This approach will allow you to use any segue between your buttons and your destination view controller. This means, you simply have to drag the blue line from the buttons to the view controller you want to segue to.
1. Within your storyboard, create a segue between your first view controller and your destination view controller. This is done by holding control, clicking on the first view controller in the interface builder, and dragging over the destination view controller. Then choose a segue type:
Now, select this segue and give it the Identifier "InitialVCToDestinationVC" in the attributes inspector:
2. Make a property called urlToPass of type URL in your initial view controller:
class InitialViewController: UIViewController {
var urlToPass: URL!
#IBAction func googleButtonPressed(_ sender: Any) {
}
#IBAction func facebookButtonPressed(_ sender: Any) {
}
}
3. Make a property called receivedUrl in the destination view controller:
class DestinationViewController: UIViewController {
var receivedUrl: URL!
#IBOutlet var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let request = URLRequest(url: receivedUrl)
webView.load(request)
}
}
4. Set the urlToPass depending on which button is pressed and use the prepareForSegue:sender: function to set the destination view controller's url accordingly. Then, make use of performSegue(withIdentifier:sender:) to perform the segue with identifier InitialVCToDestinationVC.
class InitialViewController: UIViewController {
var urlToPass: URL!
#IBAction func googleButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.google.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
#IBAction func facebookButtonPressed(_ sender: Any) {
urlToPass = URL(string: "www.facebook.com")
performSegue(withIdentifier: "InitialVCToDestinationVC", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
guard let destination = segue.destination as? DestinationViewController else { return }
destination.receivedUrl = urlToPass
urlToPass = nil
}
}
5. (optional) Make use of the shouldPerformSegueWithIdentifier:sender: method within InitialViewController and check whether or not urlToPass is valid. If urlToPass is valid, perform the segue, else present an alert.
class InitialViewController: UIViewController {
...
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if let urlToPass = urlToPass {
// check if your application can open the NSURL instance
if !UIApplication.shared.canOpenURL(urlToPass) {
let alertController = UIAlertController(title: "Cannot open URL.", message: "This is an invalid URL.", preferredStyle: .alert)
let ok = UIAlertAction(title: "Okay", style: .cancel, handler: nil)
alertController.addAction(ok)
present(alertController, animated: true, completion: nil)
}
return UIApplication.shared.canOpenURL(urlToPass)
}
return false
}
}
End result:
Here's a link to the Xcode project I made the above gif from: https://github.com/ChopinDavid/PrepareForSegue
Try using the following code snippet to pass the urlParameter to second viewcontroller
class FirstViewController: UIViewController{
func googleActionButton() {
let vc = SecondViewController()
vc.urlToOpen = "www.google.com"
self.present(vc, animated: true, completion: nil)
}
func facebookActionButton() {
let vc = SecondViewController()
vc.urlToOpen = "www.facebook.com"
self.present(vc, animated: true, completion: nil)
}
}
class SecondViewController: UIViewController{
var urlToOpen = String()
override func viewDidLoad() {
super.viewDidLoad()
// set webview url to the 'urlToOpen' which you received from FirstViewController
}
}
First of all, create an enum WebURL with all the url cases that you want to open, i.e.
enum WebURL {
case google
case facebook
var url: String {
switch self {
case .google:
return "https://www.google.com"
case .facebook:
return "https://www.facebook.com"
}
}
}
Next, in FirstVC, in the UIButton's #IBAction open SecondVC using the WebURL instance corresponding to that particular button, i.e.
class FirstVC: UIViewController{
#IBAction func openGoogle(_ sender: UIButton) {
self.openSecondVC(with: WebURL.google.url)
}
#IBAction func openFacebook(_ sender: UIButton) {
self.openSecondVC(with: WebURL.facebook.url)
}
func openSecondVC(with urlString: String) {
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondVC") as? SecondVC {
vc.urlString = urlString
self.present(vc, animated: true, completion: nil)
}
}
}
Then, use urlString in SecondVC to configure your webView, i.e.
class SecondVC: UIViewController {
var urlString: String?
override func viewDidLoad() {
super.viewDidLoad()
//Setup your webView using urlString here...
}
}

Swift: Building a Menu in a CollectionView With CollectionViewCell Segue

I am building a menu using CollectionView and programmatically trying to attach 5 buttons. I can not figure out how to connect the buttons to segues. The buttons activate a container view which then switches content within that view. This is what I have so far for the MenuContainerViewController which is embedded within a MainMenuViewController. Any help would be appreciated.
import UIKit
class MenuContainerViewController: UIViewController {
var firstVC: MainMenuViewController?
enum SegueIdentifier: String {
case SegueToTravelViewIdentifier = "SegueToTravelViewIdentifier"
case SegueToHistoryViewIdentifier = "SegueToHistoryViewIdentifier"
case SegueToLimitsViewIdentifier = "SegueToLimitsViewIdentifier"
case SegueToBalanceViewIdentifier = "SegueToBalanceViewIdentifier"
case SegueToEditViewIdentifier = "SegueToEditViewIdentifier"
case SegueToHelpViewIdentifier = "SegueToHelpViewIdentifier"
init?(optionalRawValue: String?) {
if let value = optionalRawValue {
switch value {
case "SegueToTravelViewIdentifier": self = .SegueToTravelViewIdentifier
case "SegueToHistoryViewIdentifier": self = .SegueToHistoryViewIdentifier
case "SegueToLimitsViewIdentifier": self = .SegueToLimitsViewIdentifier
case "SegueToBalanceViewIdentifier": self = .SegueToBalanceViewIdentifier
case "SegueToEditViewIdentifier": self = .SegueToEditViewIdentifier
case "SegueToHelpViewIdentifier": self = .SegueToHelpViewIdentifier
default: return nil
}
}
return nil
}
}
var vc : UIViewController!
var segueIdentifier : String!
var lastViewController: UIViewController!
override func viewDidLoad() {
super.viewDidLoad()
segueIdentifierReceivedFromParent("mainButton")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func segueIdentifierReceivedFromParent(button: String){
if button == "mainButton"
{
self.segueIdentifier = "main"
self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)
}
else if button == "travelButton"
{
self.segueIdentifier = "travel"
self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)
}
else if button == "balanceButton"
{
self.segueIdentifier = "balance"
self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)
}
else if button == "limitsButton"
{
self.segueIdentifier = "limits"
self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)
}
else if button == "historyButton"
{
self.segueIdentifier = "history"
self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)
}
else if button == "helpButton"
{
self.segueIdentifier = "help"
self.performSegueWithIdentifier(self.segueIdentifier, sender: nil)
}
}
/*
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == segueIdentifier{
if lastViewController != nil{
lastViewController.view.removeFromSuperview()
}
vc = segue.destinationViewController
self.addChildViewController(vc)
vc.view.frame = CGRect(x: 0,y: 0, width: self.view.frame.width,height: self.view.frame.height)
self.view.addSubview(vc.view)
vc.didMoveToParentViewController(self)
lastViewController = vc
}
}
*/
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let segueIdentifierValue = SegueIdentifier(rawValue: segue.identifier!) {
if lastViewController != nil {
lastViewController.view.removeFromSuperview()
}
vc = segue.destinationViewController
self.addChildViewController(vc)
vc.didMoveToParentViewController(self)
lastViewController = vc
switch segueIdentifierValue {
case .SegueToTravelViewIdentifier:
print("travel")
case .SegueToHistoryViewIdentifier:
print("history")
case .SegueToLimitsViewIdentifier:
print("limits")
case .SegueToBalanceViewIdentifier:
print("balance")
case .SegueToEditViewIdentifier:
print("edit")
case .SegueToHelpViewIdentifier:
print("help")
}
}
}
}
and this is the MainMenuViewController:
class MainMenuViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {
//Container View
#IBOutlet weak var contain: UIView!
//Slide Menu Collection View
let reuseIdentifier = "cell"
var menus = Array<String>()
var containerView: MenuContainerViewController?
#IBOutlet weak var collectionView: UICollectionView!
#IBAction func menuButtonPressed(sender: AnyObject) {
self.performSegueWithIdentifier("travel", sender: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
//Button names
menus = ["button_instore", "button_atm", "button_online", "button_travel", "button_balance", "button_limits", "button_history", "button_edit", "button_help"]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func travel(sender: AnyObject) {
containerView!.segueIdentifierReceivedFromParent("travelButton")
}
#IBAction func balance(sender: AnyObject) {
containerView!.segueIdentifierReceivedFromParent("balanceButton")
}
#IBAction func limits(sender: AnyObject) {
containerView!.segueIdentifierReceivedFromParent("limitsButton")
}
#IBAction func history(sender: AnyObject) {
containerView!.segueIdentifierReceivedFromParent("historyButton")
}
#IBAction func help(sender: AnyObject) {
containerView!.segueIdentifierReceivedFromParent("helpButton")
}
#IBAction func main(sender: AnyObject) {
containerView!.segueIdentifierReceivedFromParent("mainButton")
}
/*override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "container"{
containerView = segue.destinationViewController as? MenuContainerViewController
}
}
*/
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.navigationBar.translucent = true
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.menus.count
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
/*
func MenuContainerViewController(sender : UIButton) {
let selectedButtonCell = sender.superview as! UICollectionViewCell
let indexPath = collectionView.indexPathForCell(selectedButtonCell)
if indexPath!.row == 0 {
}
}
*/
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CollectionViewCell
//cell.menuLabel.text = self.menus[indexPath.item]
cell.menuButton?.image = UIImage(named: menus[indexPath.row])
cell.menuButtonPressed.tag = indexPath.row
//cell.menuButtonPressed.addTarget(self, action: #selector(MenuContainerViewController), forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.item)!")
}
}

My textFields doesn't disappear when is invoked viewWillAppear method in swift

import UIKit
import Alamofire
import SystemConfiguration
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var simpleLabel: UILabel!
#IBOutlet weak var uiNameSearch: UITextField!
#IBOutlet weak var uiGivenName: UITextField!
var patient1 = Patient!()
override func viewDidLoad() {
super.viewDidLoad()
uiNameSearch.delegate = self
uiGivenName.delegate = self
print("ViewController viewDidLoad")
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.simpleLabel.center.x -= self.view.bounds.width
self.uiGivenName.center.x -= self.view.bounds.width
print("Call viewWillAppear")
}
override func viewDidAppear(animated: Bool){
super.viewDidAppear(animated)
UIView.animateWithDuration(0.9 , animations: {
// self.simpleLabel.center.x += self.view.bounds.width
self.uiGivenName.center.x += self.view.bounds.width
})
UIView.animateWithDuration(0.7 , delay: 0.7, options: [], animations: {
self.uiNameSearch.center.x += self.view.bounds.width
}, completion: nil )
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func searchForName(sender: UIButton) {
let header = ["Accept" : "application/json"]
let name = uiNameSearch.text!
let given = uiGivenName.text!
if name.characters.count == 0 {
self.view.makeToast( message: "Please insert the family name of the patient!")
} else if given.characters.count == 0 {
self.view.makeToast(message: "Please insert the patient given name!")
} else if checkInternetConnection() == false {
self.view.makeToast(message: "Please connect to the internet!")
} else {
Alamofire.request(.GET, "https://open-ic.epic.com/FHIR/api/FHIR/DSTU2/Patient?family=\(name)&given=\(given)", headers: header).responseJSON { response in
self.patient1 = Patient(response: response.result.value!)
self.performSegueWithIdentifier("showSegue", sender: sender)
}
}
}
func checkInternetConnection() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
switch textField {
case uiNameSearch:
uiNameSearch.resignFirstResponder()
uiGivenName.becomeFirstResponder()
case uiGivenName:
uiGivenName.resignFirstResponder()
default:
print("")
}
return true
}
override func prepareForSegue(segue: UIStoryboardSegue, sender:AnyObject?){
if segue.identifier == "showSegue" {
if let displayViewController = segue.destinationViewController as? DisplayViewController {
displayViewController.patient1 = patient1
}
}
}
}
I want to make uiGivenName and simpleLabel to disappear until the view is created and after when the viewDidAppear is invoked to appear from the left side.
Your view doesn't disappear because you are changing position of views in viewWillAppear and when viewWillAppear gets called, view is about to be added to view hierarchy(i.e view is still not added to view hierarchy.), so its not reflecting in your UI.
So you can do your stuff in viewDidLayoutSubviews because this is the best place if you want to modify your UI just before it actually appears in the screen.
Edit -
Replace this -
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.simpleLabel.center.x -= self.view.bounds.width
self.uiGivenName.center.x -= self.view.bounds.width
print("Call viewWillAppear")
}
with
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.simpleLabel.center.x -= self.view.bounds.width
self.uiGivenName.center.x -= self.view.bounds.width
}