swift, embed ui view controller with navigation controller to allow for back button - swift

I am trying to get a back button on my MyServiceTypeSelector() controller so that after i present MyServiceTypeSelector() I can go back to the BRPServiceSelector() controller , how can i do this ? do i some how need to embed it with a nav controller and if so i am not using storyboards so it would need to be done programmatically?
import Foundation
import UIKit
class BRPServiceSelector: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
let businessAccountLabel: UILabel = {
let label = UILabel()
label.text = "Business Account"
label.backgroundColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
return label
}()
lazy var serviceSelectorButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor.black
button.setTitle("Select A Service Type?", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.addTarget(self, action: #selector(presentServiceSelector), for: .touchUpInside)
button.layer.cornerRadius = 3
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
return button
}()
func presentServiceSelector(){
let msts = MyServiceTypeSelector()
let navController = UINavigationController(rootViewController: msts)
self.present(navController, animated: true, completion: nil)
let containerView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .white
return v
}()
let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .white
return v
}()
func setupViews(){
containerView.addSubview(serviceSelectorButton)
serviceSelectorButton.anchor(top: containerView.topAnchor, left: nil, bottom: nil, right: nil, paddingTop: 50, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 220, height: 25)
serviceSelectorButton.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
}
}
}

If you want the VC in the navigation stack then push it onto the stack instead of presenting it. presenting is normally used for modal windows and they dont usually have navigation bars.
self.navigationController?.pushViewController(vc, animated: true)

Related

Why don't my selector functions get called when I clicked on my radio buttons in my Xcode Swift project

I have a custom UIView class called SortView with two radio buttons and neither of their respective selector functions are being called when I click on them. I have added an instance of the SortView class to a parent class with view.addView(). Here is my custom class:
class SortView: UIView {
// MARK: - Properties
lazy var driverSortRadioButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
button.setDimensions(height: 25, width: 25)
button.backgroundColor = .clear
button.contentMode = .scaleAspectFill
button.addTarget(self, action: #selector(handleDriverSortRadioButton), for: .touchUpInside)
return button
}()
lazy var pickupTimeSortRadioButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
button.setDimensions(height: 25, width: 25)
button.backgroundColor = .clear
button.contentMode = .scaleAspectFill
button.addTarget(self, action: #selector(handlePickupTimeSortRadioButton), for: .touchUpInside)
return button
}()
private let driverSortTitleLabel: UILabel = {
let label = UILabel()
label.text = "Sort by driver:"
label.textAlignment = .left
label.textColor = .white
label.font = UIFont(name: "AvenirNext-DemiBold", size: 18)
label.backgroundColor = .clear
return label
}()
private let pickupTimeSortTitleLabel: UILabel = {
let label = UILabel()
label.text = "Sort by pickup time:"
label.textAlignment = .left
label.textColor = .white
label.font = UIFont(name: "AvenirNext-DemiBold", size: 18)
label.backgroundColor = .clear
return label
}()
private let driverSortTextField: UITextField = {
let tf = UITextField()
tf.textColor = .black
tf.textAlignment = .center
tf.placeholder = "Louise"
tf.font = UIFont(name: "AvenirNext-DemiBold", size: 15)
tf.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
tf.setWidth(width: 150)
tf.layer.cornerRadius = 5
return tf
}()
private let pickupTimeSortTextField: UITextField = {
let tf = UITextField()
tf.textColor = .black
tf.textAlignment = .center
tf.placeholder = "2:00pm"
tf.font = UIFont(name: "AvenirNext-DemiBold", size: 15)
tf.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
tf.setWidth(width: 150)
tf.layer.cornerRadius = 5
return tf
}()
private enum radioButtonStates {
case driver
case pickupTime
}
private var radioButtonState = radioButtonStates.driver
// MARK: - Lifecycle
override init(frame: CGRect) {
super.init(frame: frame)
configureUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Selectors
#objc func handleDriverSortRadioButton() {
print("DEBUG: driver sort radio button clicked")
if radioButtonState != .driver {
pickupTimeSortRadioButton.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
pickupTimeSortTextField.isEnabled = false
pickupTimeSortTextField.text = ""
radioButtonState = .driver
driverSortRadioButton.setImage(UIImage(named: "Radio Button - Selected"), for: .normal)
driverSortTextField.isEnabled = true
driverSortTextField.text = ""
}
}
#objc func handlePickupTimeSortRadioButton() {
print("DEBUG: pickup time sort radio button clicked")
if radioButtonState != .pickupTime {
driverSortRadioButton.setImage(UIImage(named: "Radio Button - Unselected"), for: .normal)
driverSortTextField.isEnabled = false
driverSortTextField.text = ""
radioButtonState = .pickupTime
pickupTimeSortRadioButton.setImage(UIImage(named: "Radio Button - Selected"), for: .normal)
pickupTimeSortTextField.isEnabled = true
pickupTimeSortTextField.text = ""
}
}
// MARK: - Helper Functions
private func configureUI() {
let driverSortStackView = UIStackView(arrangedSubviews: [driverSortRadioButton,
driverSortTitleLabel,
driverSortTextField])
driverSortStackView.axis = .horizontal
driverSortStackView.distribution = .fill
driverSortStackView.spacing = 5
let pickupTimeSortStackView = UIStackView(arrangedSubviews: [pickupTimeSortRadioButton,
pickupTimeSortTitleLabel,
pickupTimeSortTextField])
pickupTimeSortStackView.axis = .horizontal
pickupTimeSortStackView.distribution = .fill
pickupTimeSortStackView.spacing = 5
let stackView = UIStackView(arrangedSubviews:[driverSortStackView,
pickupTimeSortStackView])
stackView.axis = .vertical
stackView.distribution = .fill
stackView.spacing = 10
self.addSubview(stackView)
stackView.centerX(inView: self)
stackView.centerY(inView: self)
}
}
The functions which are not being called are handleDriverSortRadioButton and handlePickupTimeSortRadioButton. Here is instantiation:
private lazy var sortView = SortView()
and here is where I use it in my parent UIViewController class:
view.addSubview(sortView)
sortView.anchor(top:tableView.bottomAnchor,
left: view.leftAnchor,
right: view.rightAnchor,
paddingTop: 40,
paddingLeft: 32,
paddingRight: 32)
I'm going to guess that the problem is that a containing view (perhaps one of the stack views) has zero size. The result would be that its subviews are visible but not tappable.
Here is a debugging utility method you can use to track down this sort of thing:
extension UIView {
#objc func reportSuperviews(filtering:Bool = true) {
var currentSuper : UIView? = self.superview
print("reporting on \(self)\n")
while let ancestor = currentSuper {
let ok = ancestor.bounds.contains(ancestor.convert(self.frame, from: self.superview))
let report = "it is \(ok ? "inside" : "OUTSIDE") \(ancestor)\n"
if !filtering || !ok { print(report) }
currentSuper = ancestor.superview
}
}
}
Wait until your interface is all set up and the buttons are untappable, and then call that on one of the untappable buttons to get a report in the console.
Fixed it by adding with and height to the bottom stack view
sortView.anchor(top:tableView.bottomAnchor,
left: view.leftAnchor,
right: view.rightAnchor,
paddingTop: 40,
paddingLeft: 32,
paddingRight: 32,
width: view.frame.width,
height: 100)

How to add UIImageView to navigation bar in swift?

I have this code that adds a rounded border around a UIImage using UIImageView and I've used UITapGestureRecognizer to let the user tap on the button:
var profilePicture = UIImageView()
func setupUserProfileButton() {
let defaultPicture = UIImage(named: "profilePictureSmall")
profilePicture = UIImageView(image: defaultPicture)
profilePicture.layer.cornerRadius = profilePicture.frame.width / 2
profilePicture.clipsToBounds = true
profilePicture.layer.borderColor = UIColor.black.cgColor
profilePicture.layer.borderWidth = 1
// Letting users click on the image
profilePicture.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(profilePictureTapped))
profilePicture.addGestureRecognizer(tapGesture)
}
How can I add this to the left side of a navigation bar? Is it possible? And I don't think the tap gesture is needed if I can add the ImageView to the navigation bar as a barButtonItem, so you can ignore that. I kinda found some similar questions but they were in objective C and none of what I tried worked.
Here is what I came up with based on an answer:
import UIKit
import Firebase
class CreateStoryPage: BaseAndExtensions {
let userProfileButton = UIButton(type: .custom)
override func viewDidLoad() {
super.viewDidLoad()
// Call all the elements
setupUserProfileButton()
}
// MARK:- Setups
// Setup the user profile button
func setupUserProfileButton() {
userProfileButton.setImage(#imageLiteral(resourceName: "profilePictureSmall.png"), for: .normal)
userProfileButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
userProfileButton.addTarget(self, action: #selector(profilePictureTapped), for: .touchUpInside)
let userProfileView = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
userProfileView.layer.cornerRadius = 14
userProfileView.backgroundColor = .red
userProfileView.addSubview(userProfileButton)
let leftNavBarItem = UIBarButtonItem(customView: userProfileView)
self.navigationItem.setLeftBarButton(leftNavBarItem, animated: true)
}
// if user taps on profile picture
#objc func profilePictureTapped() {
let userProfilePage = UserProfilePage()
present(userProfilePage, animated: true, completion: nil)
}
}
Try this;
private func setupRightItem() {
let userProfileButton = UIButton(type: .custom)
userProfileButton.imageView?.contentMode = .scaleAspectFill
userProfileButton.clipsToBounds = true
userProfileButton.addTarget(self, action: #selector(profilePictureTapped), for: .touchUpInside)
userProfileButton.setImage(#imageLiteral(resourceName: "profilePictureSmall.png"), for: .normal)
userProfileButton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: userProfileButton)
userProfileButton.widthAnchor.constraint(equalToConstant: 30).isActive = true
userProfileButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
}
#objc private func goProfile() {
/// -> Action
}
let navBtn = UIButton(type: .custom)
navBtn.setImage("yourImage", for: .normal)
navBtn.frame = CGRect(x: 0, y: 0, width: 28, height: 28)
navBtn.addTarget(self, action: #selector(self.openProfile(_:)), for: .touchUpInside)
let view = UIView(frame: CGRect(x: 0, y: 0, width: 28, height: 28))
view.cornerRadius = 14
view.backgroundColor = Global.colorBlue
view.addSubview(navBtn)
let leftNavBarItem = UIBarButtonItem(customView: view)
self.navigationItem.setLeftBarButton(leftNavBarItem, animated: true)
#objc
func openProfile(_ sender: UIButton) {
}

UINavigationBar not loading correctly

I know there are a lot of questions out there on this topic; however, none of those answers have helped me and I have tried so many ways of going about solving this. My problem is that my bar button will not show up, originaly, but when the viewcontroller is presented later on in the app it will show up then but the navigation title won't show up. I'm not sure why that is, but I believe it has something to do with the SwipeNavigationController framework that I'm using. My goal is to have the button show up as it's supposed to when the user swipes left to get to that view, and also when the view is later called and presented to look the same. The code for adding the navItem is below:
let cameraBarButton = UIBarButtonItem(image: #imageLiteral(resourceName: "cameraIcon"), style: .plain, target: self, action: #selector(goToCamera))
navigationItem.rightBarButtonItem = cameraBarButton
Please look at this other post to get a little better understanding of the framework. As well as here is the code on how I set up the navigation bar:
override func viewDidLoad() {
super.viewDidLoad()
setupView()
let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
let displayWidth: CGFloat = self.view.frame.width
let displayHeight: CGFloat = self.view.frame.height
messagesTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
messagesTableView.register(BlankCell.self, forCellReuseIdentifier: blankCellID)
messagesTableView.dataSource = self
messagesTableView.delegate = self
self.view.addSubview(messagesTableView)
view.backgroundColor = UIColor.white
setupNavButtons()
setupNavBar()
showNoMessagesLabel()
navigationController?.isNavigationBarHidden = false
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
} else {
// Fallback on earlier versions
}
}
override func viewWillAppear(_ animated: Bool) {
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
setupNavBar()
} else {
setupNavBar()
}
}
func setupNavBar() {
UIApplication.shared.statusBarStyle = .lightContent
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.topItem?.title = "Messages"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
self.navigationController?.navigationBar.barTintColor = UIColor.pinkNeonColor
self.navigationController?.navigationBar.tintColor = UIColor.white
}
func setupNavButtons() {
let cameraButton = UIButton(type: .system)
cameraButton.setImage(#imageLiteral(resourceName: "cameraIcon").withRenderingMode(.alwaysOriginal), for: .normal)
cameraButton.frame = CGRect(x: 0, y: 0, width: 34, height: 34)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: cameraButton)
}

UIViewController as rootViewController of UINavigationController causes root views buttons to move

When I do this in AppDelegate:
window?.rootViewController = {
let mainController = MenuViewController()
return mainController
}()
I get this:
But when I do this in AppDelegate:
window?.rootViewController = {
let mainController = UINavigationController(rootViewController: MenuViewController())
return mainController
}()
I get this:
Why and how do I fix? Please specify which information if more information is needed.
Here is the MenuView code that lays out the buttons manually and also sets up the properties of the buttons:
class MenuView: UIView {
//title
let titleLabel: UILabel = {
let label = UILabel()
label.text = "Survive The Attackers!!"
label.backgroundColor = UIColor.white
return label
}()
//set up buttons
let newGameButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("New Game", for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
button.backgroundColor = UIColor.white
button.layer.borderWidth = 2.0;
button.layer.borderColor = UIColor.black.cgColor
return button
}()
let resumeButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Resume Game", for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
button.backgroundColor = UIColor.white
button.layer.borderWidth = 2.0;
button.layer.borderColor = UIColor.black.cgColor
return button
}()
let highScoresButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("High Scores", for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
button.backgroundColor = UIColor.white
button.layer.borderWidth = 2.0;
button.layer.borderColor = UIColor.black.cgColor
return button
}()
//add subviews and initialize the view
override init(frame: CGRect){
super.init(frame: frame)
self.backgroundColor = UIColor(patternImage: UIImage(named: "background1.png")!)
addSubview(titleLabel)
addSubview(newGameButton)
addSubview(resumeButton)
addSubview(highScoresButton)
}
required init?(coder aDecoder: NSCoder) {
fatalError("It's Apple. What did you expect?")
}
//manually layout the main menu
override func layoutSubviews() {
var cursor: CGPoint = .zero
let buttonHeight = CGFloat(40.0);
let buttonWidth = CGFloat(160.0);
let labelWidth = buttonWidth + 20;
let spacing = bounds.height/4
let titleY = 2/3 * spacing
cursor.y = titleY
cursor.x = bounds.width/2 - labelWidth/2
titleLabel.frame = CGRect(x: cursor.x, y: cursor.y, width: labelWidth, height: buttonHeight)
cursor.y = spacing
cursor.x = bounds.width/2 - buttonWidth/2
newGameButton.frame = CGRect(x: cursor.x, y: cursor.y, width: buttonWidth, height: buttonHeight)
cursor.y += spacing
resumeButton.frame = CGRect(x: cursor.x, y: cursor.y, width: buttonWidth, height: buttonHeight)
cursor.y += spacing
highScoresButton.frame = CGRect(x: cursor.x, y: cursor.y, width: buttonWidth, height: buttonHeight)
}
The buttons are laid out manually in layoutSubviews
Here is my MenuView controller code:
class MenuViewController: UIViewController {
var delegateID: String = UUIDVendor.vendUUID()
private var menuView: MenuView {
return view as! MenuView
}
init(){
super.init(nibName: nil, bundle: nil)
//edgesForExtendedLayout = .init(rawValue: 0)
}
required init?(coder aDecoder: NSCoder){
fatalError()
}
//loads the view in and sizes it correctly
override func loadView() {
view = MenuView()
//extendedLayoutIncludesOpaqueBars = false
}
override func viewDidLoad() {
menuView.newGameButton.addTarget(self, action: #selector(MenuViewController.newGameButtonTapped(button:)), for: .touchUpInside)
menuView.resumeButton.addTarget(self, action: #selector(MenuViewController.resumeGameButtonTapped(button:)), for: .touchUpInside)
menuView.highScoresButton.addTarget(self, action: #selector(MenuViewController.highScoreButtonTapped(button:)), for: .touchUpInside)
menuView.setNeedsLayout()
}
//fuction that handles the event when the newGameButton is tapped
#objc func newGameButtonTapped(button: UIButton){
//reset the data in the model somehow
navigationController?.pushViewController(GameViewController(), animated: true)
}
//function that handles the event when the resume game button is tapped
#objc func resumeGameButtonTapped(button: UIButton){
}
//function that handels the event when the high scores button is tapped
#objc func highScoreButtonTapped(button: UIButton){
}
call super for layoutSubviews
private var menuView: MenuView = {
let vw = MenuView()
return vw
}()
override func viewDidLoad() {
super.viewDidLoad()
view = MenuView() //Add here
//Your code
}
And remove loadView() from MenuViewController

Create segue objects programmatically

I created a single view app with 2 view controllers. In the first view controller, I have a label and 2 buttons that were programmatically created. I have 2 segues from these buttons to the second view controller. I wish that each button carries different information to the second view controller. From creating these buttons and segues programmatically, I haven’t been able to assign the identifier to the segues. So, I can’t use performSegue(withIdentifier: sender:).
How can I do this?
First ViewController:
import UIKit
class ViewController: UIViewController {
var myLabel: UILabel!
var leftButton: UIButton!
var rightButton: UIButton!
// bellow are the 2 variable which I’d like to transport into the second ViewController
var leftButtonText = "I'm the left button."
var rightButtonText = "I'm the right button."
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let homeNavBar = UINavigationBar()
homeNavBar.frame = CGRect(x: 0, y: 0, width: 320, height: 45)
homeNavBar.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(homeNavBar)
let homeNavItem = UINavigationItem(title: "Home")
homeNavBar.setItems([homeNavItem], animated: false)
myLabel = UILabel()
myLabel.frame = CGRect(x: 165, y: 150, width: 200, height: 42)
myLabel.text = "Press one of the button bellow!"
self.view.addSubview(myLabel)
leftButton = UIButton(type: .custom)
leftButton.frame = CGRect(x: 80, y: 300, width: 70, height: 70)
leftButton.backgroundColor = UIColor.cyan
leftButton.setTitleColor(UIColor.black, for: .normal)
leftButton.setTitle("Left Button", for: .normal)
leftButton.layer.cornerRadius = 20
leftButton.layer.borderWidth = 1
leftButton.layer.masksToBounds = true
leftButton.addTarget(self, action: #selector(ViewController.leftButtonAction(_:)), for: .touchUpInside)
self.view.addSubview(leftButton)
rightButton = UIButton(type: .custom)
rightButton.frame = CGRect(x: 240, y: 300, width: 70, height: 70)
rightButton.backgroundColor = UIColor.cyan
rightButton.setTitleColor(UIColor.black, for: .normal)
rightButton.setTitle("Right button", for: .normal)
rightButton.layer.cornerRadius = 20
rightButton.layer.borderWidth = 1
rightButton.layer.masksToBounds = true
rightButton.addTarget(self, action: #selector(ViewController.rightButtonAction(_:)), for: .touchUpInside)
self.view.addSubview(rightButton)
let margins = self.view.layoutMarginsGuide
homeNavBar.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
homeNavBar.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
homeNavBar.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
myLabel.topAnchor.constraint(equalTo: homeNavBar.bottomAnchor).isActive = true
leftButton.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
leftButton.topAnchor.constraint(equalTo: myLabel.bottomAnchor).isActive = true
rightButton.topAnchor.constraint(equalTo: myLabel.bottomAnchor).isActive = true
rightButton.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
}
#objc func leftButtonAction (_ sender: UIButton) {
let segueSecondViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "idSecond")
self.show(segueSecondViewController, sender: nil)
print("I'm activated by the left button.")
}
#objc func rightButtonAction (_ sender: UIButton) {
let segueSecondViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "idSecond")
self.show(segueSecondViewController, sender: nil)
print("I'm activated by the right button.")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Second ViewController:
import UIKit
class SecondViewController: UIViewController {
var mySecondLabel: UILabel!
var mySecondLabelText = "I'm the second page."
var closeButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let secondNavBar = UINavigationBar()
secondNavBar.frame.size = CGSize(width: 320, height: 45)
secondNavBar.translatesAutoresizingMaskIntoConstraints = false
let secondNavItem = UINavigationItem(title: "Second page")
secondNavBar.setItems([secondNavItem], animated: false)
self.view.addSubview(secondNavBar)
mySecondLabel = UILabel()
mySecondLabel.frame = CGRect(x: 165, y: 200, width: 200, height: 42)
mySecondLabel.backgroundColor = UIColor.yellow
mySecondLabel.textColor = UIColor.black
mySecondLabel.text = "\(mySecondLabelText)"
mySecondLabel.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(mySecondLabel)
closeButton = UIButton(type: .custom)
closeButton.frame = CGRect(x: 10, y: 50, width: 50, height: 50)
closeButton.backgroundColor = UIColor.red
closeButton.setTitleColor(UIColor.black, for: .normal)
closeButton.setTitle("Close", for: .normal)
closeButton.layer.cornerRadius = 30
closeButton.layer.borderWidth = 1
closeButton.layer.masksToBounds = true
closeButton.addTarget(self, action: #selector(SecondViewController.closeButtonAction(_:)), for: .touchUpInside)
self.view.addSubview(closeButton)
let margins = self.view.layoutMarginsGuide
secondNavBar.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
secondNavBar.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
secondNavBar.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
closeButton.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
closeButton.topAnchor.constraint(equalTo: secondNavBar.bottomAnchor).isActive = true
mySecondLabel.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
mySecondLabel.topAnchor.constraint(equalTo: closeButton.bottomAnchor).isActive = true
mySecondLabel.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
}
#objc func closeButtonAction (_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
print("Second page closed.")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
You can do it by giving your View Controller an Identifier. This isn't a segue, but it will Instantiate your target VC:
let vc = UIStoryboard(name:"Main", bundle:nil).instantiateViewControllerWithIdentifier("identifier") as! SecondViewController
self.navigationController?.pushViewController(vc, animated:true)
You can set the VC Identifier on the Identity Inspector tab on the StoryBoard.
I just read in the documentation that you can't call the performSegue method if you don't have a segue with an identifier in the Storyboard, so WRT your requirement, you can't do it programmatically.
identifier The string that identifies the triggered segue. In
Interface Builder, you specify the segue’s identifier string in the
attributes inspector.