Swift Protocol delegation not working - ios

I have a viewController that has a containerView with pageView. Once I slide a view from the pageView I want to call a function in the viewController I have tried with my code below but it is calling buttonMaskColor please where would be my issue?
class PlaceMenuDetailsViewController: UIViewController, PageViewSliderDelegate {
override func viewDidLoad() {
super.viewDidLoad()
detailsButton.pageDelegation = self
}
func buttonMaskColor(){
println("delegate work")
}
}
class DetailPageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
weak var pageDelegation:PageViewSliderDelegate?
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
pageDelegation?.buttonMaskColor()
var page = (viewController as! PageDelegate).pageNumber + 1
return viewControllerForPage(page)
}

You should assign self to pageDelegation in your prepareForSegue function in your mainView after giving and identifier for the embed segue like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "embedSegueIdentifier" {
let distinationVC = segue.destinationViewController as? DetailPageViewController
distinationVC?.pageDelegation = self
}
}

Related

Delegate returns nil and not being called

I have an overlay that I want to remove when a button is clicked thereby dismissing the ViewController. I have debugged and the delegate is currently returning nil. I'm not sure what I'm doing wrong here. Have I missed implementing something else? I have even tried out print statements but can't see anything.
protocol DismissOverlayDelegate: class {
func dismissOverlay(_ sender: PlayersViewController)
}
class PlayersViewController: UIViewController {
weak var delegate: DismissOverlayDelegate?
#IBAction func getStartedTapped(_ sender: UIButton) {
self.delegate?.dismissOverlay(self)
}
}
and in my ViewController where I implement the delegate method
class HomeViewController: UIViewController, DismissOverlayDelegate {
#IBOutlet weak var customOverlay: CustomOverlayView!
let playersViewController = PlayersViewController()
override func viewDidLoad() {
super.viewDidLoad()
self.playersViewController.delegate = self
}
func dismissOverlay(_ sender: PlayersViewController) {
self.customOverlay.removeFromView()
}
}
delegate = (DismissOverlayDelegate?) nil
The PlayersViewController is embedded into a UIPageViewController
class HomeViewController: UIPageViewController, UIPageViewControllerDataSource {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
for storyboardIDs in ["playersVC1","playersVC2"] {
let viewController = self.storyboard?.instantiateViewController(withIdentifier: storyboardIDs)
self.pages.append(viewController!)
}
self.dataSource = self
self.setViewControllers([self.pages.first!], direction: .forward, animated: true)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = self.pages.firstIndex(of: viewController)!
if currentIndex > 0 {
return self.pages[currentIndex - 1]
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = self.pages.firstIndex(of: viewController)!
if currentIndex < (self.pages.count - 1) {
return self.pages[currentIndex + 1]
}
return nil
}
}
It seems that PlayersViewController() is wrong.
You should use instantiateInitialViewController() or instantiateInitialViewController() when using StoryBoard.
https://developer.apple.com/documentation/uikit/uistoryboard/1616214-instantiateviewcontroller
https://developer.apple.com/documentation/uikit/uistoryboard/1616213-instantiateinitialviewcontroller
Let me explain you if you are using or want to use delegate for call or implement something there is root and you have to that on a right way. You are doing well no issue but the implementation of delegate is not properly your method can't accept that so try this:-
Your Home View Controller
class HomeViewController: UIViewController, DismissOverlayDelegate {
#IBOutlet weak var customOverlay: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
func dismissOverlay(_ sender: PlayersViewController) {
self.customOverlay.removeFromSuperview()
}
#IBAction func go(_ sender: UIButton) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "PlayersViewController") as! PlayersViewController
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true);
}
}
this is your playground VC
protocol DismissOverlayDelegate: class {
func dismissOverlay(_ sender: PlayersViewController)
}
class PlayersViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
weak var delegate: DismissOverlayDelegate?
#IBAction func getStartedTapped(_ sender: UIButton) {
self.delegate?.dismissOverlay(self)
}
}
now hope you understand what you have to do...!

Change Label text in a ContainerView on click of a button from other class (Uiviewcontroller)

I got small containerView with UILabel on main app screen. I got UIButton on main UIViewController. I want to change text of label that belongs to containerView class by clicking button in UIViewController.
I try to make it with delegation, but for some reason i got a mistake (Unwraping optional)...
I try to make it with Protocol, bud method "addText" in ContView dont works((((((
class ViewController: UIViewController {
var delegate: DelegateProtocol?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func button(_ sender: Any) {
delegate?.addText(String2: "123")
}}
///////////////////////////////////////////////////////////////////////
protocol DelegateProtocol {
func addText(String2: String)
}
//////////////////////////////////////////////////////////////////////
class ContViewController: UIViewController, DelegateProtocol {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "con" {
let vc = segue.destination as! ViewController
vc.delegate = self
}
}
func addText(String2: String) {
label.text = String2
}
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}
first make an global variable in your view controller
private var viewController: YourVC?
then give your container view segue an identifier and do follwing
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourviewcontroller Segue identifiew" { //your container view segue identifier
viewController = segue.destination as? SelectedImageVC
}
}
now you can use you viewController to access label in your containerview controller like
if let controller = viewController {
controller.yourlabel.text = "text you want"
}

Delegate function not being called iOS Swift

Here I am trying to pass value from one class LanguageSelectionTVC to another RegistrationVC by using a Protocol.
When I try and call the method self.delegate?.setSelectedLangauges(self.languagesSpokenArray) inside LanguageSelectionTVC it doesn't call the method setSelectedLangauges inside the class Registration VC could someone please suggest where I am going wrong ?
protocol LanguageSelectionTVCProtocol {
func setSelectedLangauges(_ valueSent: [String])
}
class LanguageSelectionTVC: UITableViewController {
var delegate : LanguageSelectionTVCProtocol? = nil
func saveAndClose() {
self.delegate?.setSelectedLangauges(self.languagesSpokenArray)
dismiss()
}
}
class RegistrationVC: UIViewController,
UITableViewDelegate,
UITableViewDataSource,
LanguageSelectionTVCProtocol{
func setSelectedLangauges(_ valueSent: [String]){
self.showLanguagesSpoken(valueSent)
}
}
Moving to LanguageSelectionTVC from RegistrationVC . The below tableView method is in my RegistrationVC
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let row = indexPath.row
let section = indexPath.section
let currentCell = tableView.cellForRow(at: indexPath) as! UITableViewCell
if section == 4 && row == 0 {
// The user has clicked on languages spoken cell
self.performSegue(withIdentifier: "LanguageSelectionTVC", sender: self)
}
}
You need to access LanguageSelectionTVC from preparForSegue to set delegate of it. So override the prepare(for:sender:) in your RegistrationVC.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "LanguageSelectionTVC" {
let vc = segue.destination as! LanguageSelectionTVC
vc.delegate = self
}
}
You need to set the delegate in RegistrationVC to LanguageSelectionTVC, for example you could set it when performing a segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let targetVC = segue.destination as! LanguageSelectionTVC
targetVC.delegate = self
}
You need to set delegate. can you please see below ready example for pass data between two view controller.
import UIKit
protocol SenderViewControllerDelegate
{
func messageData(str1:NSString)
}
class tableViewController: UIViewController, UITableViewDelegate,
UITableViewDataSource
{
var delegate: tableViewController?
override func viewDidLoad()
{
super.viewDidLoad()
self.delegate?.messageData(str1: “Hello world”)
}
}
receive data in below controller
import UIKit
class HomeViewController: UIViewController ,SenderViewControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let objtableview = tableViewController(nibName: "tableViewController",bundle: nil)
objtableview.delegate = self
self.navigationController?.pushViewController(objtableview, animated: true)
}
func messageData(str1:NSString){
print(str1)
}
}

How can I run delegated method inside IBAction?

I have some methods in second view controller. I access them through delegate - inside func buttonSender. Main goal is to pass currentTitle of a button as an argument to a viewController.addNewMessage. What is the best way to do this?
ChatViewController:
protocol ReactToButtons {
func buttonSender(viewController: MyChatViewController)
}
class MyChatViewController: ChatViewController{
var delegate: ReactToButtons?
override func viewDidLoad() {
super.viewDidLoad()
delegate!.buttonSender(self)
}
}
ContainerViewController:
class ContainerViewController: UIViewController, ReactToButtons {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let myVC = segue.destinationViewController as! MyChatViewController
myVC.delegate = self
}
func buttonSender(viewController: MyChatViewController) {
viewController.addNewMessage(/*HERE GOES CURRENT TITLE*/)
}
#IBAction func leftButtonPressed(sender: AnyObject) {
let currentTitle = sender.currentTitle!
}
I have change my answer to suit your code
class ContainerViewController: UIViewController, ReactToButtons {
var delegate: MyChatViewController!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let myVC = segue.destinationViewController as! MyChatViewController
myVC.delegate = self
}
func buttonSender(viewController: MyChatViewController) {
delegate = viewController
}
#IBAction func leftButtonPressed(sender: AnyObject) {
let currentTitle = sender.currentTitle!
delegate!.addNewMessage(currentTitle)
}
}

Overriding Swiping Actions on a UITableView over UIPageController VC segues

In swift, i'm currently working on segueing my VC's using a UIPageViewController, where when you swipe left or right it changes the VC. In one of my View Controllers, a table view exists, where if you swipe on the row there are options. My problem is, when I swipe on the row of the table, it changes to my View Controller. I want to override this so that it shows row actions before VC swiping. My code below is the first VC. PS: If you need my Code for my tableviews please comment for it! Thanks
import UIKit
class ViewController: UIViewController, UIPageViewControllerDataSource {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var myViewControllers = Array(count: 4, repeatedValue:UIViewController())
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
let pvc = segue.destinationViewController as UIPageViewController
pvc.dataSource = self
let storyboard = UIStoryboard(name: "Main", bundle: nil);
var vc0 = storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as UIViewController
var vc1 = storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as UIViewController
var vc2 = storyboard.instantiateViewControllerWithIdentifier("ThirdViewController") as UIViewController
var vc3 = storyboard.instantiateViewControllerWithIdentifier("FourthViewController") as UIViewController
self.myViewControllers = [vc0, vc1, vc2, vc3]
pvc.setViewControllers([myViewControllers[1]], direction:.Forward, animated:false, completion:nil)
println("Loaded")
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var currentIndex = find(self.myViewControllers, viewController)!+1
if currentIndex >= self.myViewControllers.count {
return nil
}
return self.myViewControllers[currentIndex]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var currentIndex = find(self.myViewControllers, viewController)!-1
if currentIndex < 0 {
return nil
}
return self.myViewControllers[currentIndex]
}
}
Did the tableView takes all the space in your view? let's try with
override func scrollViewDidScroll(scrollView: UIScrollView) {
}

Resources