userDefualt not saving switch when class is segued - swift

My swift code below which is all code no storyboard. Tries to save a switch's state using user defaults. So when the user segues to twoViewController and then segues backs to ViewController. The users switch setting is not being saved. There are no errors presented and I don't know what is going on.
import UIKit
class ViewController: UIViewController {
var nxtBTn = UIButton()
var mySwitch = UISwitch()
let userDefaults = UserDefaults.standard
var firstTimeAppLaunch: Bool {
get {
// Will return false when the key is not set.
return userDefaults.bool(forKey: "firstTimeAppLaunch")
}
set {}
}
#objc func switchAction(_ sender: UISwitch) {
userDefaults.set(sender.isOn, forKey: "mySwitchValue")
}
#objc func press() {
let segue = twoViewController()
segue.modalPresentationStyle = .fullScreen // actually .fullScreen would be better
self.present(segue, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
[nxtBTn,mySwitch].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
view.addSubview($0)
$0.backgroundColor = .green
}
if !firstTimeAppLaunch {
// This will only be trigger first time the application is launched.
userDefaults.set(true, forKey: "firstTimeAppLaunch")
userDefaults.set(true, forKey: "mySwitchValue")
}
NSLayoutConstraint.activate([
nxtBTn.leadingAnchor.constraint(equalTo: view.leadingAnchor),
nxtBTn.topAnchor.constraint(equalTo: view.topAnchor),
nxtBTn.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 7/7, constant: 0),
nxtBTn.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.4, constant: 0),
mySwitch.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mySwitch.bottomAnchor.constraint(equalTo: view.bottomAnchor),
mySwitch.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 7/7, constant: 0),
mySwitch.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.4, constant: 0),
])
mySwitch.addTarget(self, action: #selector(switchAction(_:)), for: .touchDown)
nxtBTn.addTarget(self, action: #selector(press), for: .touchDown)
view.backgroundColor = .white
}
override func viewDidAppear(_ animated: Bool) {
mySwitch.isOn = userDefaults.bool(forKey: "mySwitchValue")
}
}
class twoViewController : UIViewController{
var backBtn = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
backBtn.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(backBtn)
backBtn.backgroundColor = .systemGreen
NSLayoutConstraint.activate([
backBtn.leadingAnchor.constraint(equalTo: view.leadingAnchor),
backBtn.topAnchor.constraint(equalTo: view.topAnchor),
backBtn.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 7/7, constant: 0),
backBtn.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.4, constant: 0),
])
backBtn.addTarget(self, action: #selector(oneVC), for: .touchDown)
}
#objc func oneVC(){
let segue = ViewController()
segue.modalPresentationStyle = .fullScreen // actually .fullScreen would be better
self.present(segue, animated: true)
}
}

Everywhere you are saying for: .touchDown it is wrong. Change all of them to for: .primaryActionTriggered and things will improve.

Related

Why I am not successfull to use segue programmatically?

I am using storyboard for ScreenOne, and I did not use the storyboard for ScreenTwo, I was coding as programmatically and until now no problem for me, but I am still not success to declare
"storyboardIdentifier" for ScreenTwo. Here there is an example but I don't understand how I will handle this example inside of the app. Any idea will be appreciated.
Screenshot:
ScreenTwo:
class ForgotPasswordEmailCheckController: UIViewController {
var storyboardId: String {
return (value(forKey: "ForgotPasswordEmailCheckController") as? String)!
}
Storyboard Controller (Also Embed this controller in Navigation Controller):
class FirstVC: UIViewController {
#IBOutlet weak var btn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
btn.addAction(UIAction(handler: { action in
let secondVC = SecVC()
self.navigationController?.pushViewController(secondVC, animated: true)
}), for: .touchUpInside)
}
}
Second Viewcontroller:
class SecVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.blue
}
}
This is programmatically way to do it:
in sceneDelegate set your initial navigation controller:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
let controller = UINavigationController(rootViewController: MyController())
window?.rootViewController = controller
}
now configure your navigationBar in firstController, use my extension to do it:
extension UIViewController {
func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
if #available(iOS 13.0, *) {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
navBarAppearance.backgroundColor = backgoundColor
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.compactAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.tintColor = tintColor
navigationItem.title = title
} else {
// Fallback on earlier versions
navigationController?.navigationBar.barTintColor = backgoundColor
navigationController?.navigationBar.tintColor = tintColor
navigationController?.navigationBar.isTranslucent = false
navigationItem.title = title
}
}
}
This is your first controller looks like:
class MyController: UIViewController {
let button = UIButton() // declare your button
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationBar(largeTitleColor: .white, backgoundColor: .black, tintColor: .white, title: "My Vc", preferredLargeTitle: true) // set nav bar with exetnsion
view.backgroundColor = .white
view.addSubview(button)
button.backgroundColor = .systemBlue
button.layer.cornerRadius = 9
button.setTitle("My Button", for: .normal)
button.addTarget(self, action: #selector (handelGoToSecondVc), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16).isActive = true
button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16).isActive = true
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
}
#objc func handelGoToSecondVc() {
let controller = SecondController()
controller.title = "second Vc"
navigationController?.pushViewController(controller, animated: true)
}
}
second controller:
class SecondController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
}
}
This is the result:
Complete code:
import UIKit
class MyController: UIViewController {
let button = UIButton() // declare your button
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationBar(largeTitleColor: .white, backgoundColor: .black, tintColor: .white, title: "My Vc", preferredLargeTitle: true) // set nav bar with exetnsion
view.backgroundColor = .white
view.addSubview(button)
button.backgroundColor = .systemBlue
button.layer.cornerRadius = 9
button.setTitle("My Button", for: .normal)
button.addTarget(self, action: #selector (handelGoToSecondVc), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16).isActive = true
button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16).isActive = true
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
}
#objc func handelGoToSecondVc() {
let controller = SecondController()
controller.title = "second Vc"
navigationController?.pushViewController(controller, animated: true)
}
}
class SecondController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
}
}
extension UIViewController {
func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
if #available(iOS 13.0, *) {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
navBarAppearance.backgroundColor = backgoundColor
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.compactAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.tintColor = tintColor
navigationItem.title = title
} else {
// Fallback on earlier versions
navigationController?.navigationBar.barTintColor = backgoundColor
navigationController?.navigationBar.tintColor = tintColor
navigationController?.navigationBar.isTranslucent = false
navigationItem.title = title
}
}
}

UISegmentedControl: segment overlapping when pass data back

thanks Duncan C. I edit my question:
i have a ViewControllerA with a 3 segments SegmentedControl, on ViewControllerB you can delete one segment and go back to VCA.
when I do so, I have, in VCA, 2 segments (the new segments after deletion) over the 3 segments (the 3 segments initially loaded).
VCA before change
VCA after change
I understand that it has to do with the view cycle, the initial ViewDidLoad persists, but even passing through viewWillAppear I still have this result.
this project is not a real project, just a test to solve the problem I have on my initial project.
my code for VCA:
class VCA: UIViewController, Info {
// array which contains the name for the segmentedControl
var array = ["Peter", "Bob", "Jim"]
var segmentedControl: UISegmentedControl!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setView(array: array)
}
override func viewDidLoad() {
super.viewDidLoad()
}
// delegate protocol: receive data from VCB
func passData(array: [String]) {
self.array = array
}
func setView(array: [String]) {
segmentedControl = UISegmentedControl(items: array)
segmentedControl.selectedSegmentIndex = 0
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("OK", for: .normal)
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
let stackView = UIStackView()
stackView.axis = .vertical
stackView.distribution = .fillEqually
stackView.spacing = 50
stackView.addArrangedSubview(segmentedControl)
stackView.addArrangedSubview(button)
view.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
stackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
stackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20),
stackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20)])
}
#objc func buttonTapped() {
let destinationVC = VCB()
destinationVC.array = array
destinationVC.infoDelegate = self
destinationVC.modalPresentationStyle = .fullScreen
present(destinationVC, animated: true, completion: nil)
}
}
my code for VCB:
class VCB: UIViewController {
// array which contains the name of the segments
var array = [String]()
// delegate to send data back
var infoDelegate: Info!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
setView(array: array)
}
func setLabel(array: [String]) -> String {
var labelText = "the array contains"
for name in array {
labelText += " \(name)"
}
return labelText
}
func setView(array: [String]) {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.text = setLabel(array: array)
view.addSubview(label)
view.backgroundColor = .cyan
NSLayoutConstraint.activate([
label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
label.centerXAnchor.constraint(equalTo: view.centerXAnchor)])
let button = UIButton(type: .system)
button.setTitle("Delete the first name in the array", for: .normal)
button.addTarget(self, action: #selector(backTapped), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
NSLayoutConstraint.activate([
button.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 40),
button.centerXAnchor.constraint(equalTo: label.centerXAnchor)])
}
#objc func backTapped() {
array.remove(at: 0)
infoDelegate.passData(array: array)
dismiss(animated: true, completion: nil)
}
}
with a protocol to send data back to VCB:
protocol Info {
func passData(array: [String])
}
any ideas/help?
thanks a lot
I gather VCA is view controller A and VCB is view controller B. You're saying that from VCB you delete one segment of VCA's segmented controller?
You should not mess with another view controller's views.
You will need to post your code and explain how the user navigates between view controllers in order for us to be able to help you.
(And by the way, those huge segmented controls look absurd. You should leave them at the standard height.)
I think I have found a solution. I remove all segments of the UISegment before repopulating it with the new data received from ViewController B.
func passData(array: [String]) {
self.array =array
segmentedControl.removeAllSegments()
segmentedControl = UISegmentedControl(items: array)
}
If the solution seems to work, it is not very elegant.

setup google maps as view

after I finish setting up google maps I have added three subviews UIButton it's clickable I think its works fine, and UIView and on the top of the UIView I have added UITextField as (Subview) But I can't use it I can't input anything it's not editable
so when I comment google map code everything works fine the textField that I but in UIView will allow editing works fine
import UIKit
import GoogleMaps
class GoogleMap: UIViewController, UITextFieldDelegate {
let locationBtn: UIButton = {
let button = UIButton(type: .system)
button.addTarget(self, action: #selector(orderBtnAction), for: UIControl.Event.touchUpInside)
button.setTitle("إستخدام هذا الموقع", for: UIControl.State.normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 15)
button.tintColor = UIColor.white
button.layer.cornerRadius = 10
button.backgroundColor = UIColor.delevareColor
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
let locationView: UIView = {
let view = UIView()
view.layer.cornerRadius = 15
view.backgroundColor = UIColor.white
view.layer.shadowPath = UIBezierPath(rect: view.bounds).cgPath
view.layer.shadowRadius = 5
view.layer.shadowOffset = .zero
view.layer.shadowOpacity = 1
view.clipsToBounds = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let currentLocTextField: UITextField = {
let textField = UITextField()
textField.text = "جاري تحميل موقعك..."
textField.font = UIFont.boldSystemFont(ofSize: 19)
textField.textColor = UIColor.black
textField.borderStyle = .roundedRect
textField.isUserInteractionEnabled = true
textField.translatesAutoresizingMaskIntoConstraints = false
textField.textAlignment = .center
return textField
}()
var locationManager = CLLocationManager()
var mapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
currentLocTextField.delegate = self
locationView.addSubview(currentLocTextField)
setUpNavigationController()
setUpGoogleMap()
setUpLayout()
}
func setUpLayout() {
locationBtn.heightAnchor.constraint(equalToConstant: 50).isActive = true
locationBtn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
locationBtn.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -25).isActive = true
locationBtn.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 10).isActive = true
locationBtn.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10).isActive = true
locationView.heightAnchor.constraint(equalToConstant: 120).isActive = true
locationView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
locationView.bottomAnchor.constraint(equalTo: locationBtn.topAnchor, constant: -10).isActive = true
locationView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 10).isActive = true
locationView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10).isActive = true
currentLocTextField.heightAnchor.constraint(equalToConstant: 30).isActive = true
currentLocTextField.centerXAnchor.constraint(equalTo: locationView.centerXAnchor).isActive = true
currentLocTextField.topAnchor.constraint(equalTo: locationView.topAnchor, constant: 20).isActive = true
currentLocTextField.leftAnchor.constraint(equalTo: locationView.leftAnchor, constant: 20).isActive = true
currentLocTextField.rightAnchor.constraint(equalTo: locationView.rightAnchor, constant: -50).isActive = true
}
func setUpGoogleMap(){
let camera = GMSCameraPosition.camera(withLatitude: 15.592778, longitude: 32.552278, zoom: 12)
mapView = GMSMapView.map(withFrame: .zero, camera: camera)
view = mapView
mapView.animate(to: camera)
mapView.isMyLocationEnabled = true
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
mapView.delegate = self
mapView.addSubview(locationBtn)
mapView.addSubview(locationView)
}
}
extension GoogleMap: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard status == .authorizedWhenInUse else {
return
}
locationManager.startUpdatingLocation()
mapView.isMyLocationEnabled = true
mapView.settings.myLocationButton = true
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else {
return
}
// 7
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 15, bearing: 0, viewingAngle: 0)
// 8
locationManager.stopUpdatingLocation()
}
}
extension GoogleMap: GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
return
}
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {
if #available(iOS 11.0, *) {
reverseGeocodeCoordinate(position.target)
} else {
// Fallback on earlier versions
}
}
}
Change you setup method
func setUpGoogleMap(){
let camera = GMSCameraPosition.camera(withLatitude: 15.592778, longitude: 32.552278, zoom: 12)
mapView = GMSMapView.map(withFrame: self.view.bounds, camera: camera)
view .addSubview( mapView)
mapView.animate(to: camera)
mapView.isMyLocationEnabled = true
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
mapView.delegate = self
// mapView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(locationBtn)
self.view.addSubview(locationView)
}

UITextField not working with add constraints programmatically

Here is my code , I am adding UITextfield programtically in scrollview. But UITextField is unable to open keyboard.
It looks like UITextField is not enabling even added user interaction enabled true.
I only use the constraints, no storyboard, no xibs. Only through Constraints Programmatically.
Below is my code :
class SignupViewController : UIViewController {
var backButton : UIButton!
var titleLabel : UILabel!
var navBarView : UIView!
var scrollView : UIScrollView!
var scrollMainView : UIView!
var emailfieldView : UIView!
var emailTextField : UITextField = UITextField() override func viewDidLoad() {
super.viewDidLoad()
setDesign()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
}func setDesign(){
setNavegationBar()
setBackgroundImage()
addScrollView()
}
func setBackgroundImage(){
let backgroundImage = UIImageView(image: UIImage(named: "loginbg.png"))
self.view.addSubview(backgroundImage)
backgroundImage.translatesAutoresizingMaskIntoConstraints = false
let leadingConst = backgroundImage.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
let trailingConst = backgroundImage.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
let topConst = backgroundImage.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0)
let bottomConst = backgroundImage.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
NSLayoutConstraint.activate([leadingConst,trailingConst,topConst,bottomConst])
}
func setNavegationBar(){
navigationItem.title = "Join"
view.backgroundColor = UIColor.white
navigationController?.navigationBar.isHidden = true
navigationController?.navigationBar.tintColor = UIColor.white
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
setNavBarView()
}
func setNavBarView(){
navBarView = UIView()
self.view.addSubview(navBarView)
navBarView.translatesAutoresizingMaskIntoConstraints = false
let guide = view.safeAreaLayoutGuide
let heightCost = navBarView.heightAnchor.constraint(equalToConstant: 64.0)
let leadingCost = navBarView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0.0)
let trailingConst = navBarView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
let topCost = navBarView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0.0)
NSLayoutConstraint.activate([trailingConst,heightCost,topCost,leadingCost])
setBackButton()
setNavTitle()
}
func setBackButton(){
backButton = UIButton(type: UIButtonType.custom)
backButton.setImage(UIImage(named: "join_back"), for: UIControlState.normal)
navBarView.addSubview(backButton)
backButton.translatesAutoresizingMaskIntoConstraints = false
let widthCost = backButton.widthAnchor.constraint(equalToConstant: 44.0)
let heightCost = backButton.heightAnchor.constraint(equalToConstant: 44.0)
let leadingCost = backButton.leadingAnchor.constraint(equalTo: navBarView.leadingAnchor, constant: 0.0)
let topCost = backButton.topAnchor.constraint(equalTo: navBarView.topAnchor, constant: 0.0)
NSLayoutConstraint.activate([widthCost,heightCost,topCost,leadingCost])
backButton.addTarget(self, action: #selector(self.backButtonPress), for: UIControlEvents.touchUpInside)
}
func setNavTitle(){
titleLabel = UILabel()
titleLabel.text = "Join Dubai Store"
titleLabel.font = UIFont(name: "Dubai-Regular", size: 22.0)
titleLabel.textAlignment = NSTextAlignment.center
titleLabel.tintColor = UIColor(hexString: "#353535")
navBarView.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
let heightCost = titleLabel.heightAnchor.constraint(equalToConstant: 44.0)
let topCost = titleLabel.topAnchor.constraint(equalTo: navBarView.topAnchor, constant: 0.0)
let centerCost = titleLabel.centerXAnchor.constraint(equalTo: navBarView.centerXAnchor)
NSLayoutConstraint.activate([heightCost,topCost,centerCost])
}
#objc func backButtonPress(){
self.view.endEditing(true)
self.dismissView()
}
func addScrollView(){
scrollView = UIScrollView()
view.addSubview(scrollView)
scrollView.layer.borderWidth = 1.0
scrollView.layer.borderColor = UIColor.red.cgColor
scrollView.translatesAutoresizingMaskIntoConstraints = false
let leadingConst = scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
let trailingConst = scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
let topConst = scrollView.topAnchor.constraint(equalTo: navBarView.bottomAnchor, constant: 0)
let bottomConst = scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
NSLayoutConstraint.activate([leadingConst,trailingConst,topConst,bottomConst])
addScrollMainView()
}
func addScrollMainView() {
scrollMainView = UIView()
scrollView.addSubview(scrollMainView)
scrollMainView.translatesAutoresizingMaskIntoConstraints = false
let leadingConst = scrollMainView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 0)
let trailingConst = scrollMainView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
let topConst = scrollMainView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0)
let bottomConst = scrollMainView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0)
NSLayoutConstraint.activate([topConst,leadingConst,trailingConst,bottomConst])
emailFieldView()
}
func emailFieldView(){
emailfieldView = UIView()
emailfieldView.isUserInteractionEnabled = true
emailfieldView.translatesAutoresizingMaskIntoConstraints = false
scrollMainView.addSubview(emailfieldView)
let topCost = emailfieldView.topAnchor.constraint(equalTo: scrollMainView.topAnchor, constant: 0.0)
let leadingConst = emailfieldView.leadingAnchor.constraint(equalTo: scrollMainView.leadingAnchor, constant: 0)
let trailingConst = emailfieldView.trailingAnchor.constraint(equalTo: scrollMainView.trailingAnchor, constant: 0)
let heightCost = emailfieldView.heightAnchor.constraint(equalToConstant: 62.0)
NSLayoutConstraint.activate([trailingConst,heightCost,topCost,leadingConst])
//emailTextField = UITextField(frame: CGRect(x: 10, y: 0, width: SCREEN_WIDTH, height: 50))
emailTextField.placeholder = "Email"
emailTextField.layer.borderColor = UIColor.red.cgColor
emailTextField.layer.borderWidth = 1.0
// emailTextField.font = UIFont.systemFont(ofSize: 15)
// emailTextField.borderStyle = UITextBorderStyle.none
// emailTextField.keyboardType = UIKeyboardType.default
// emailTextField.returnKeyType = UIReturnKeyType.done
// //emailTextField.clearButtonMode = UITextFieldViewMode.whileEditing
emailTextField.isUserInteractionEnabled = true
emailTextField.allowsEditingTextAttributes = true
//emailTextField.contentVerticalAlignment = UIControlContentVerticalAlignment.center
emailTextField.addTarget(self, action: #selector(self.textFieldShouldBeginEditing), for: UIControlEvents.touchUpInside)
emailfieldView.addSubview(emailTextField)
emailTextField.translatesAutoresizingMaskIntoConstraints = false
emailTextField.contentMode = UIViewContentMode.left
emailTextField.delegate = self
let etopCost = emailTextField.topAnchor.constraint(equalTo: emailfieldView.topAnchor, constant: 0.0)
let eleadingConst = emailTextField.leadingAnchor.constraint(equalTo: emailfieldView.leadingAnchor, constant: 10)
let etrailingConst = emailTextField.trailingAnchor.constraint(equalTo: emailfieldView.trailingAnchor, constant: -10)
let eheightCost = emailTextField.heightAnchor.constraint(equalToConstant: 50.0)
NSLayoutConstraint.activate([etopCost,eleadingConst,etrailingConst,eheightCost])
self.scrollMainView.bringSubview(toFront: emailTextField)
emailTextField.isAccessibilityElement = true
} }
extension SignupViewController: UITextFieldDelegate {
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
// return NO to disallow editing.
print("TextField should begin editing method called")
return true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
// became first responder
print("TextField did begin editing method called")
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
// return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
print("TextField should snd editing method called")
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
// may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
print("TextField did end editing method called")
}
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
// if implemented, called in place of textFieldDidEndEditing:
print("TextField did end editing with reason method called")
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// return NO to not change text
print("While entering the characters this method gets called")
return true
}
func textFieldShouldClear(_ textField: UITextField) -> Bool {
// called when clear button pressed. return NO to ignore (no notifications)
print("TextField should clear method called")
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// called when 'return' key pressed. return NO to ignore.
print("TextField should return method called")
// may be useful: textField.resignFirstResponder()
return true
}
}
I just run your code, it looks like scrollMainView is not visible in the views' hierarchy. Just change the constraints. Here is the code:
func addScrollMainView() {
scrollMainView = UIView()
scrollView.addSubview(scrollMainView)
scrollMainView.translatesAutoresizingMaskIntoConstraints = false
let leadingConst = scrollMainView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
let trailingConst = scrollMainView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
let topConst = scrollMainView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0)
let bottomConst = scrollMainView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
NSLayoutConstraint.activate([topConst,leadingConst,trailingConst,bottomConst])
emailFieldView()
}
BTW, It is not related to your question, but it is better to create bg at the beginning. Just use the code below:
func setDesign(){
setBackgroundImage()
setNavegationBar()
addScrollView()
}

Can't dismiss ModalViewController

I've got a problem by dismissing a ViewController programmatically.
I connected both Controllers and if I press the Button, the Controller will be presented.
Here is my prepareForSegue method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let VC = VC()
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurredView = UIVisualEffectView(effect: blurEffect)
blurredView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + 64)
VC.view.frame = self.view.bounds
VC.view.backgroundColor = UIColor.clearColor()
VC.view.addSubview(blurredView)
VC.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
var masterViewOfVC = (segue.destinationViewController as! SubjectSelectionViewController).masterView
blurredView.addSubview(masterViewOfVC)
masterViewOfVC.setTranslatesAutoresizingMaskIntoConstraints(false)
let views = ["masterView": masterViewOfVC]
let horizontalConstraintsForMasterView = NSLayoutConstraint.constraintsWithVisualFormat("H:|[masterView]|", options: .AlignAllCenterY, metrics: nil, views: views)
blurredView.addConstraints(horizontalConstraintsForMasterView)
let verticalConstraintsForMasterView = NSLayoutConstraint.constraintsWithVisualFormat("V:|[masterView]|", options: .AlignAllCenterX, metrics: nil, views: views)
blurredView.addConstraints(verticalConstraintsForMasterView)
(segue.destinationViewController as! VC).viewDidLoad()
self.presentViewController(VC, animated: true, completion: nil)
}
So and if I try to dismiss it it doesn't do anything. I already checked if the buttons works and it does.
Here is my code from the other controller:
//viewDidLoad
cancelButton.setTitle("Abbrechen", forState: UIControlState.Normal)
cancelButton.tintColor = UIColor.whiteColor()
cancelButton.addTarget(self, action: Selector("buttonAction:"), forControlEvents: UIControlEvents.TouchUpInside)
cancelButton.enabled = true
//my function
func buttonAction(sender:UIButton!) {
VC().dismissViewControllerAnimated(true, completion: nil)
}
UPDATE
I delete the segue in my Storyboard and I created a modal segue in the IBAction of my Button. I also initialise my "dismiss button" in this action.
Here is my code from the parentViewController:
#IBAction func SubjectSelctionButtonPressed(sender: UIBarButtonItem) {
let subjectSelectionViewController = SubjectSelectionViewController()
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurredView = UIVisualEffectView(effect: blurEffect)
blurredView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + 64)
subjectSelectionViewController.view.frame = self.view.bounds
subjectSelectionViewController.view.backgroundColor = UIColor.clearColor()
subjectSelectionViewController.view.addSubview(blurredView)
subjectSelectionViewController.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
var masterViewOfSubjectSelection = SubjectSelectionViewController().masterView
var buttonOfSubjectSelection = SubjectSelectionViewController().cancelButton
buttonOfSubjectSelection.setTitle("Abbrechen", forState: UIControlState.Normal)
buttonOfSubjectSelection.tintColor = UIColor.whiteColor()
buttonOfSubjectSelection.addTarget(self, action: Selector("buttonAction:"), forControlEvents: UIControlEvents.TouchUpInside)
blurredView.addSubview(masterViewOfSubjectSelection)
masterViewOfSubjectSelection.addSubview(buttonOfSubjectSelection)
masterViewOfSubjectSelection.setTranslatesAutoresizingMaskIntoConstraints(false)
let views = ["masterView": masterViewOfSubjectSelection]
let horizontalConstraintsForMasterView = NSLayoutConstraint.constraintsWithVisualFormat("H:|[masterView]|", options: .AlignAllCenterY, metrics: nil, views: views)
blurredView.addConstraints(horizontalConstraintsForMasterView)
let verticalConstraintsForMasterView = NSLayoutConstraint.constraintsWithVisualFormat("V:|[masterView]|", options: .AlignAllCenterX, metrics: nil, views: views)
blurredView.addConstraints(verticalConstraintsForMasterView)
self.presentViewController(subjectSelectionViewController, animated: true, completion: nil)
}
and the action from the button looks like this:
func buttonAction(sender:UIButton!) {
dismissViewControllerAnimated(true, completion: nil)
}
ok now, when the controller is presenting there is nothing except my elements which I created in the action. My viewDidLoad() method of my presenting Controller is called but the constraints and the formattings doesn't get called...
Here is my viewDidLoad() of my modalViewController:
titleLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
cancelButton.setTranslatesAutoresizingMaskIntoConstraints(false)
separatorLine.setTranslatesAutoresizingMaskIntoConstraints(false)
subjectsTableView.setTranslatesAutoresizingMaskIntoConstraints(false)
subjectsTableView.delegate = self
titleLabel.text = "Unterrichtsfächer"
titleLabel.textColor = UIColor.whiteColor()
titleLabel.font = UIFont(name: "HelveticaNeue-Medium", size: 17)
separatorLine.backgroundColor = UIColor.whiteColor()
subjectsTableView.backgroundColor = UIColor.clearColor()
masterView.addSubview(titleLabel)
masterView.addSubview(cancelButton)
masterView.addSubview(separatorLine)
masterView.addSubview(subjectsTableView)
let views = ["line": separatorLine, "title": titleLabel, "button": cancelButton, "table": subjectsTableView]
let verticalConstraintsForElements = NSLayoutConstraint.constraintsWithVisualFormat("V:|-64-[line(2)][table]|", options: .AlignAllCenterX, metrics: nil, views: views)
masterView.addConstraints(verticalConstraintsForElements)
let horizontalConstraintsForSeparatorLine = NSLayoutConstraint.constraintsWithVisualFormat("H:|[line]|", options: .AlignAllCenterY, metrics: nil, views: views)
masterView.addConstraints(horizontalConstraintsForSeparatorLine)
let horizontalConstraintsForTableView = NSLayoutConstraint.constraintsWithVisualFormat("H:|[table]|", options: .AlignAllCenterY, metrics: nil, views: views)
masterView.addConstraints(horizontalConstraintsForTableView)
let verticalConstraintsForTitleLabel = NSLayoutConstraint.constraintsWithVisualFormat("V:[title(21)]-11-[line]", options: .AlignAllCenterX, metrics: nil, views: views)
masterView.addConstraints(verticalConstraintsForTitleLabel)
let horizontalAlignmentForTitleLabel = NSLayoutConstraint(item: titleLabel, attribute: NSLayoutAttribute.CenterX, relatedBy: .Equal, toItem: masterView, attribute: .CenterX, multiplier: 1, constant: -18)
masterView.addConstraint(horizontalAlignmentForTitleLabel)
let widthForTitleLabel = NSLayoutConstraint(item: titleLabel, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 137)
masterView.addConstraint(widthForTitleLabel)
let verticalConstraintsForCancelButton = NSLayoutConstraint.constraintsWithVisualFormat("V:[button(30)]-6-[line]", options: .AlignAllCenterX, metrics: nil, views: views)
masterView.addConstraints(verticalConstraintsForCancelButton)
let horizontalConstraintsForCancelButton = NSLayoutConstraint.constraintsWithVisualFormat("H:[button(90)]-7-|", options: .AlignAllCenterY, metrics: nil, views: views)
masterView.addConstraints(horizontalConstraintsForCancelButton)
Can anybody help me?
Thank you very much!!!
Your problem is that you are not pushing the other view to dismiss it, you are just adding the new view controller on top of the other view
You need to substitute this line
blurredView.addSubview(masterViewOfVC)
For
presentViewController(masterViewOfVC, animated: true, completion: nil)
Now when you call dismiss view controller all should just work
I haven't really checked all your code but to fix it quickly, you can make the instance of VC a class property.
So it'll look something like this:
class MainViewController: UIViewController {
var VC = UIViewController() // I would use an optional here but I've been down voted for suggesting people to use optionals.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
VC = VC()
// Your code
}
func buttonAction(sender:UIButton!) {
VC.dismissViewControllerAnimated(true, completion: nil)
}
}
Here I'm assuming you're using some kind of master - detail view so buttonAction is still accessible when you segue to VC.
If buttonAction is a method in VC itself, then just call dissmissViewControllerAnimated() on self with:
func buttonAction(sender:UIButton!) {
dismissViewControllerAnimated(true, completion: nil)
}
Either way, you'll have to call dissmissViewControllerAnimated() on the instance of VC. With VC() you'll just create a new instance which has "nothing" to do with the one that already exists.
Update:
If you've created SubjectSelectionViewController() in your storyboard, then you probably would want to instantiate it with:
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let subjectSelectionViewController = storyboard.instantiateViewControllerWithIdentifier("YourIdentifier") as! SubjectSelectionViewController