Swift 3.0 Delegate Protocol doesn't work - ios

I have made delegate protocol within two view controllers. but the delegate method doesn't call on my code snippet. what is the reason for that. I couldn't find out the issue kindly post your suggestions to relive this issue.
Main View controller
class ViewController: UIViewController, testDelegateMethod {
override func viewDidLoad() {
super.viewDidLoad()
let vw = testViewController()
vw.delegateTest = self
let push = self.storyboard?.instantiateViewController(withIdentifier: "testViewController")
self.navigationController?.pushViewController(push!, animated: true)
}
func testMethod(value:String) {
print("Hai", value)
}
}
Sub View controller
protocol testDelegateMethod {
func testMethod(value:String)
}
class testViewController: UIViewController {
var delegateTest : testDelegateMethod?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func actSubmit(_ sender: Any) {
delegateTest?.testMethod(value: "Hello how are you!")
}
}

The issue you are facing due to this line
let vw = testViewController()
vw.delegateTest = self
You have created instance of testViewController vw, and Assigned delegate of vw instance
In the next line
let push = self.storyboard?.instantiateViewController(withIdentifier: "testViewController")
self.navigationController?.pushViewController(push!, animated: true)
You are creating different instance of testviewcontroller push
There is no need of this code,
let vw = testViewController()
vw.delegateTest = self
Instead do
let push testViewController = self.storyboard.instantiateViewController(withIdentifier: "testViewController") as! testViewController
push.delegateTest = self
self.navigationController?.pushViewController(push, animated: true)

Update these changes in viewdidLoad() method
override func viewDidLoad() {
super.viewDidLoad()
if let push = self.storyboard?.instantiateViewController(withIdentifier: "testViewController") as? SelectionScreen
{
push.delegateTest = self
}
}

This code snippet does not make sense. You just create an object but does not use it further. So remove this code snippet.
let vw = testViewController()
vw.delegateTest = self
And do like this:
override func viewDidLoad() {
super.viewDidLoad()
let pushVC = self.storyboard?.instantiateViewController(withIdentifier: "testViewController") as! testViewController
pushVC.delegateTest = self
self.navigationController?.pushViewController(pushVC, animated: true)
}

I think, you put code func testMethod(value:String) {
print("Hai", value)
}
into viewDidLoad and above let push = self.storyboard?.instantiateViewController(withIdentifier: "testViewController")
self.navigationController?.pushViewController(push!, animated: true)

let vw = testViewController() // Your are doing wrong code
vw.delegateTest = self
Use only this
I hope it will work for you
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let push = storyboard.instantiateViewController(withIdentifier:"testViewController")as! testViewController
push.delegateTest = self
self.navigationController?.pushViewController(push, animated: true)

Related

How could I pass data to childView

About
I'm developping ios app with MXParallaxHeader.
I use it in order to create twitter-like UI.
However, I don't know how to pass data from MXScrollView to childViewController when I go MXScrollView page.
Question
How could I pass data from MXScrollView to childViewController?
Sample Code
PreviousViewController
//MXScrollViewController=ParentVC of MarkerInfoTabViewController
class PreviousViewController:UIViewController {
.
.
#IBAction func goMXScrollView(_ sender: Any) {
let nextView = self.storyboard?.instantiateViewController(withIdentifier: "MXScrollViewController") as! MXScrollViewController
self.navigationController?.pushViewController(nextView, animated: true)
}
}
childViewController
//MarkerInfoTabViewController(=childVC of MXScrollView)
import Tabman
import UIKit
import MXParallaxHeader
class MarkerInfoTabViewController: TabmanViewController {
var marker:Marker!
private var viewControllers = [UIViewController?]()
override func viewDidLoad() {
super.viewDidLoad()
let leftView = self.storyboard?.instantiateViewController(withIdentifier: "MarkerInfoLeftViewController") as! MarkerInfoLeftViewController
let rightView = self.storyboard?.instantiateViewController(withIdentifier: "MarkerInfoRightViewController") as! MarkerInfoRightViewController
//↓I want to pass data here
leftView.marker = marker
viewControllers = [leftView, rightView]
self.dataSource = self
// Create bar
let bar = TMBar.ButtonBar()
bar.layout.transitionStyle = .snap // Customize
// Add to view
addBar(bar, dataSource: self, at: .top)
}
}
My App Image
・storyboard
・segue to header
・segue to childVC
Reference
My app is mostly the same as this app.
Just define a property in the child controller class
class ChildViewController {
var passedData: MY_DATA_TYPE
...
and set it after the instantiation
let nextView = self.storyboard?.instantiateViewController(withIdentifier: "ChildViewController") as! ChildViewController
nextView.passedData = MY_PASSED_DATA
self.navigationController?.pushViewController(nextView, animated: true)

Navigation Controller is not loading ( push , present ) another viewController

I cannot load the viewController on clicking the button, knowing that the defined Vc holds a value of the VC that i want to present.
//AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let mainViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ViewController") as! ViewController
let navVC = UINavigationController.init(rootViewController: mainViewController)
self.window?.rootViewController = navVC
self.window?.makeKeyAndVisible()
return true
}
//ViewController Class
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var collectionView: UICollectionView!
#IBOutlet weak var button: UIButton!
#IBOutlet weak var pageController: UIPageControl!
private let reuseIdentifier = /*"CollectionViewCell"*/ "Cell"
let collectionViewImages : [UIImage] = [#imageLiteral(resourceName: "cooov"), #imageLiteral(resourceName: "shutterstock535739452"), #imageLiteral(resourceName: "portraitYoungManLyingBedCheckingHisFeverThermometer232147948490")]
let collectionViewTexts : [String] = [
"Stay at home ! your health is our Priority",
"Access Latest Coronavirus articles !",
"Check up on your health on a daily basis !"
]
override func viewDidLoad() {
super.viewDidLoad()
renderButton()
renderCell()
pageController.numberOfPages = collectionViewImages.count
pageController.currentPage = 0
}
#IBAction func buttonClicked(_ sender: UIButton) {
let signupVC = UIStoryboard.init(name:"SignUp", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
as! SignUp
self.navigationController?.pushViewController(signupVC, animated: true)
}
}
//SignUp class The VC that should appear on ButtonClick
class SignUp : BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
//the class that is inherited by ViewController
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
}
}
[enter image description here][1]}
enter image description here
here is a link to the pics provided please check.
https://drive.google.com/drive/folders/1CxysH911PIa3-S9Dx6EUV7DE8vlnEd4l?usp=sharing
Here is the function you can change it like this and let me know the outcome
first run this one
#IBAction func buttonClicked(_ sender: UIButton) {
let signupVC = UIStoryboard.init(name:"SignUp", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
let navVC = UINavigationController.init(rootViewController: signupVC)
// self.present(navVC, animated: true, completion: nil)
if let nav = self.navigationController {
nav.pushViewController(navVC, animated: true)
} else {
print("navigation controller not found")
}
}
And then try to present ... and let me know what happened
#IBAction func buttonClicked(_ sender: UIButton) {
let signupVC = UIStoryboard.init(name:"SignUp", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
let navVC = UINavigationController.init(rootViewController: signupVC)
self.present(navVC, animated: true, completion: nil)
}
You don't need new UINavigation controller to push.
#IBAction func buttonClicked(_ sender: UIButton) {
let signupVC = UIStoryboard.init(name:"SignUp", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
as! SignUp
self.navigationController?.pushViewController(signupVC, animated: true)
}
Also if you are working with iOS 13.0+ and using Xcode 11+, your
SceneDelegate will be called instead of AppDelegate. So try copying the paste to SceneDelegate as well.

Delegate function not calling

I have 2 UIViewControllers, ViewController, SecondViewController. I defined delegate function in VC, and using in Second VC. But delegate functions not calling in Second VC.
This is mu first VC code
import UIKit
//Step1:
protocol testDelegate {
func testFunction(string1: String, string2:String)
func math(a:Int, b:Int)
}
class ViewController: UIViewController {
//Step2:
var delegateVariable: testDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func moveToSecondVC(_ sender: Any) {
let nav = self.storyboard?.instantiateViewController(withIdentifier: "SVC") as! SecondViewController
//Step3:
delegateVariable?.testFunction(string1: "String1", string2: "String2")
delegateVariable?.math(a:30, b:10)
self.navigationController?.pushViewController(nav, animated: true)
}
}
My second VC code
import UIKit
//Step4:
class SecondViewController: UIViewController , testDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//Step5:
let svc = ViewController()
svc.delegateVariable = self
}
#IBAction func btn(_ sender: Any) {
//Step5:
let svc = ViewController()
svc.delegateVariable = self
}
//Step6:
func testFunction(string1: String, string2: String) {
print(string1+string2)
}
func math(a:Int, b:Int) {
print(a+b)
print(a-b)
print(a*b)
}
}
Here i'm just passing small amount of data for practice, but can any one please suggest some high level delegate example tutorial links for me.
This is why nothing is happening...
let svc = ViewController()
svc.delegateVariable = self
You are creating a NEW ViewController, not using the one that is actually in use.
It does not look like you are using the delegate pattern properly. Your ViewController should not be calling code on other view controllers.
SecondViewController should "do stuff" and then let ViewController know what it has done.
For the Math function you could just use a new class (not a view controller) and create and use this as needed. You do not need a ViewController for this.
An example of using a delegate might be something like:
protocol CreateProfileDelegate: class {
func didCreateProfile(profile: Profile?)
func didCancelCreateProfile()
}
class ViewController: UIViewController {
func showCreateProfile() {
let vc = CreateProfileViewController()
vc.delegate = self
present(vc, animated: true)
}
}
extension ViewController: CreateProfileDelegate {
func didCreateProfile(profile: Profile?) {
// show the profile?
}
func didCancelCreateProfile() {
// show an alert maybe?
}
}
This way the SecondViewController (CreateProfileViewController) basically tells the first that something has happened so that it can react to it.
in SecondViewController you are setting....
let svc = ViewController()
svc.delegateVariable = self
That just create an object of ViewController() class and then you set the delegate. So when the obj. of the scope is finished then the memory of the object will be increased automatically.
The flow should like below....
Create an object of the Viewcontroller in SecondViewController and set the delegate
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
vc.delegateVariable = self
Then push the view controller in to the navigation stack.
self.navigationController?.pushViewController(svc, animated: true)
Implement the delegate method of testDelegate in SecondViewController
func testFunction(string1: String, string2: String) {
print(string1+string2)
}
func math(a:Int, b:Int) {
}
EDIT
The final code of the SecondViewController Will be...
import UIKit
class SecondViewController: UIViewController , testDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btn(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
vc.delegateVariable = self
self.navigationController?.pushViewController(svc, animated: true)
}
//MARK:- TestDelegate Methods
func testFunction(string1: String, string2: String) {
print(string1+string2)
}
func math(a:Int, b:Int) {
print(a+b)
print(a-b)
print(a*b)
}
}

How to set up a title at the top of a ViewController

In my app I have a tabBarViewController, and this is the first bar:
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
}
override func viewWillAppear(_ animated: Bool) {
self.navigationItem.title = "RECENTS"
}
}
this is the custom class:
class CustomTabBar: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let firstVC = FirstViewController()
let secondVC = SecondViewController()
let thirdVC = ThirdViewController()
firstVC.tabBarItem.title = "RECENT"
secondVC.tabBarItem.title = "MAP"
thirdVC.tabBarItem.title = "SETTINGS"
firstVC.title = "RECENT"
secondVC.title = "MAP"
thirdVC.title = "SETTINGS"
viewControllers = [firstVC,secondVC,thirdVC]
}
}
So my question is: How can I put a title at the top of the view controller?
In the previous code I tried, but it's not working!
Something like this:
The title property is shown when a view controller is wrapped in a UINavigationController. Here's some code replacing the last line (i.e. the viewControllers assignment) in of your example that should do the trick:
let firstNC = UINavigationController(rootViewController: firstVC)
let secondNC = UINavigationController(rootViewController: secondVC)
let thirdNC = UINavigationController(rootViewController: thirdVC)
viewControllers = [firstNC,secondNC,thirdNC]
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.navigationItem.title = "My Title"
}
This should work. I hope it helps you.
Or if you can try this.
let vc3 = UINavigationController(rootViewController: SearchVC())
vc3.tabBarItem.image = UIImage(named: "vyhledavani")
vc3.title = "Vyhledat"
vc3.tabBarItem.tag = 2
viewControllers = [vc3, ...]

Can we handle the error "Cannot convert the value of type BOOL to expected argument UIiew"

I am tired of trying to PopOver the view controller and searched every where, tried myself also.This issue has again arrived and i am confused what to do next
func showPopover(base: UIView)
{
let storyboard : UIStoryboard = UIStoryboard(name: "Messaging", bundle: nil)
if let viewController = storyboard.instantiateViewControllerWithIdentifier("PreferencesViewController") as?PreferencesViewController
{
let navController = UINavigationController(rootViewController: viewController)
navController.modalPresentationStyle = .Popover
if let pctrl = navController.popoverPresentationController
{
pctrl.delegate = self
pctrl.sourceView = base
pctrl.sourceRect = base.bounds
self.presentViewController(navController, animated: true, completion: nil)
}
}
}
I am calling this method in any one of the actions clicked from UIBarButtons
func optionChoosed(hello:Bool)
{
if (hello)
{
self.showPopover(hello)
}
}
it says Cannot convert the value of type BOOL to expected argument UIiew.. can we fix this or am i going wrong direction.
class SHNewStylesViewController: UIViewController, UIPopoverPresentationControllerDelegate {
var popover: UIPopoverPresentationController? = nil
//MARK: - View life cycle
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//MARK: - IBActions
#IBAction func showPopover(sender: AnyObject) {
let genderViewController = storyboard!.instantiateViewControllerWithIdentifier("ViewControllerTwoIdentifier") as! ViewControllerTwo
genderViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
genderViewController.preferredContentSize = CGSize(width: 200.0, height: 400.0) // To change the popover size
popover = genderViewController.popoverPresentationController!
popover!.barButtonItem = sender as? UIBarButtonItem
popover!.delegate = self
presentViewController(genderViewController, animated: true, completion:nil)
}
//MARK: - Popover Presentation Controller Delegate methods
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
}
In my case showPopover is a IBAction of my bar button item. You can you that code inside the showPopover method wherever you want.
Thanks:)

Resources