i have a ViewController which is already loaded from the beginning of the app Lunching i need when the user logout from his AccountViewController ,so the Logout Icon in Side menu got hidden.
So in the Homepage i made that Protocol :
protocol HomeViewControllerDelegate {
func Menucheck()
}
then assign the delegate in ViewDidload():
var delegate: HomeViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
delegate?.Menucheck()
then in the Side MenuViewController i did like that:
in ViewDidLoad():
let secondVC = Storyborad.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
secondVC.delegate = self
then i have used the delegate function like that:
extension SideMenuViewController: HomeViewControllerDelegate {
func Menucheck() {
print("i can hear you :) ")
if(preferences.double(forKey: User_ID) == 0)
{
LogoutSideIcon.isHidden = true
}else {
LogoutSideIcon.isHidden = false
}
}
Now when i go to homeViewController i suppose to see ("i can hear you") at least ,but actually nothing happen,i have tried to add to (Viewdidload) instead ,and i have tried to add it to a button action but nothing is happen ...
Related
I'm a beginner trying to learn iOS.
I'm trying to show a sheet, but I'm finding it's not really showing anything.
This is what it looks like:
This is my relevant code:
class ViewController: UIViewController {
#IBAction func openMemoryLog(_ sender: UIButton) {
let memoryLogViewController = MemoryLogViewController()
present(memoryLogViewController, animated: true)
}
}
class MemoryLogViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("Memory log loaded")
if let presentationController = presentationController as? UISheetPresentationController {
presentationController.detents = [ .medium() ]
}
}
}
I can see the print statement going through, so it's at least loading. But don't know what's going on here. Looks like some sort of modal thing is happening, but the IB interface isn't showing.
When you use Storyboard / IB to design an interface, you have to instantiate that controller from the Storyboard - you cannot simply assign the class to a variable.
#IBAction func openMemoryLog(_ sender: UIButton) {
// if you designed MemoryLogViewController in Storyboard,
// you cannot create it like this:
//let memoryLogViewController = MemoryLogViewController() <-- wrong
// you need to instantiate it from the Storyboard
// for example, if you gave your controller a Storyboard ID of "memoryLogViewController":
if let memoryLogViewController = storyboard?.instantiateViewController(withIdentifier: "memoryLogViewController") {
present(memoryLogViewController, animated: true)
}
}
I have a todo list that allows the user to add todos to a table view. On a separate view controller (CompletedViewController) the user can see previously-completed todos.
There is an itemBarButton in the CompletedViewController that should allow the user to clear the list of completed items, as well as clear the array of completed todos (completedThings) on the initial ViewController.
Creating an instance of CompletedViewController and setting the completedTodos array in ViewController.swift:
#IBAction func viewCompletedTapped(_ sender: Any) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "Completed") as? CompletedViewController {
vc.completedTodos = completedThings
navigationController?.pushViewController(vc, animated: true)
}
}
the protocol in CompletedViewController.swift:
protocol CompletedCleared {
func didClearCompleted()
}
the method called when clicking the 'clear' itemBarButton in CompletedViewController.swift
#objc func clearCompleted() {
completedTodos = []
tableView.reloadData()
let vc = ViewController()
vc.didClearCompleted()
}
conforming to the protocol in ViewController.swift
func didClearCompleted() {
completedThings.removeAll()
}
This does not clear the list on the previous view controller. What am I doing wrong?
You forgot to set the delegate of the CompletedViewController. In viewCompletedTapped add this line after instantiating the view controller:
vc.delegate = self
Also make sure you use this delegate method in CompletedViewController. clearCompleted should probably look like this:
#objc func clearCompleted() {
completedTodos = []
tableView.reloadData()
delegate?.didClearCompleted()
}
I'm getting nil when unwrapping an optional value with GADBannerView..
I setup my ad banner like this, in FlashViewController.swift..
class FlashViewController: UIViewController {
#IBOutlet weak var bannerView: GADBannerView!
and then in ViewDidLoad:
func initAdMobBanner() {
bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716"
bannerView.rootViewController = self
bannerView.load(GADRequest())
}
bannerView has an outlet in storyboard to Root View Controller, which is class FlashViewController.
Then in TableViewController.swift I have my purchase button. Purchase button runs:
FlashViewController().HideMyBanner();
The function HideMyBanner is in FlashViewController and will run this code:
if bannerView != nil {
print("bannerview Contains a value!")
bannerView.isHidden = true
} else {
print("bannerview Doesn’t contain a value.")
}
The issue is, if I create a button directly in FlashViewContorller.swift and run the same function, bannerView contains a value and can be hidden.. If I call the function from TableViewController.swift, it returns nil, (or crashes if I try to hide bannerView... I feel like I missing something easy here, but already spent a long time trying to figure it out...
By using this line FlashViewController().HideMyBanner(); you are creating new object of FlashViewController. so it will crash.you need to use the object of FlashViewController which is already created and loaded in memory.
I think you need to pass the reference of FlashViewContorller to TableViewController
If your TableViewController is load from FlashViewContorller than you need to create reference FlashViewContorller in TableViewController like this way.
class TableViewController: UIViewController {
var objFlashViewContorller : FlashViewContorller?
override func viewDidLoad() {
super.viewDidLoad()
//This is the UILabel
}
func purchasebuttonClick() {
objFlashViewContorller?.HideMyBanner();
}
}
While setup Navigation FlashViewContorller to TableViewController you need to pass reference.
let tableViewController = self.storyboard!.instantiateViewController(withIdentifier: "TableViewController") as! TableViewController
tableViewController.objFlashViewContorller = self
self.navigationController?.pushViewController(tableViewController, animated: true)
OR
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "TableViewController" {
let vc = segue.destinationViewController as! TableViewController
vc.objFlashViewContorller = self
}
Don't use FlashViewController().HideMyBanner();
I think you need to use this in in TableViewController.swift -> my purchase button method.
self.revealViewController.frontViewController.HideMyBanner()
I used Notifications to finally work this out... Controller 2 sends a notification that a purchase has been made, and Controller 1 observes and waits for this notification, then takes care of hiding the banner in Controller 1.
https://blog.bobthedeveloper.io/pass-data-with-nsnotification-in-swift-3-73743723c84b
I'm new to swift and my problem right now is I want to pass the value from RoutePreviewController page back to display on ViewController page after clicking on the Navigate Button. As below picture, you can see that the RoutePreviewController is not directly segue from the ViewController.
This is my story board of the swift project on xcode
However, I tried using protocol and delegate in the code.
Here are codes that I have add to the ViewController (MainPage)
protocol HandleSelectedPath{
func selectedPathDraw(selectedRoute:[(line:Int?,node:Int,time:Double)])
}
in viewDidLoad of ViewController
let routePreviewPage = storyboard!.instantiateViewControllerWithIdentifier("RoutePreviewController") as! RoutePreviewController
routePreviewPage.handleSelectedPathDelegate = self
and an extension outside the ViewController class
extension ViewController : HandleSelectedPath{
func selectedPathDraw(selectedRoute:[(line:Int?,node:Int,time:Double)]){
print("7687980")
selectedPath = selectedRoute
routeDraw()
}
}
And in RoutePreviewController, I have delegation of the protocol.
var handleSelectedPathDelegate: HandleSelectedPath? = nil
and the Navigate button action
#IBAction func navigateButtonAction(sender: AnyObject) {
handleSelectedPathDelegate?.selectedPathDraw(previewPath)
dismissViewControllerAnimated(true, completion: nil)
definesPresentationContext = true
}
As a result, after clicking the Navigate button, it does send me back to the ViewController page but the selectedPathDraw function of the protocol is not performed. I also tried printing some random string but nothing came up as an output.
The reference for your RoutePreviewController according to your code above only exist inside your viewDidLoad, you have to set as property instead like this:
var routePreviewPage: RoutePreviewController!
Always it's a good practice implement your delegate as a weak reference to avoid retain-cycles, so the correct way of implement your delegate and protocol should be as the following code:
protocol HandleSelectedPath: class {
func selectedPathDraw(selectedRoute:[(line:Int?,node:Int,time:Double)])
}
RoutePreviewController:
weak var handleSelectedPathDelegate: HandleSelectedPath?
#IBAction func navigateButtonAction(sender: AnyObject) {
handleSelectedPathDelegate?.selectedPathDraw(previewPath)
dismissViewControllerAnimated(true, completion: nil)
definesPresentationContext = true
}
viewDidLoad of ViewController:
routePreviewPage = storyboard!.instantiateViewControllerWithIdentifier("RoutePreviewController") as! RoutePreviewController
routePreviewPage.handleSelectedPathDelegate = self
I hope this help you.
I'm working on authorization based on google accounts to my app. I have a settings view that contains the following code:
import UIKit
import Google
class Settings: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let background = CAGradientLayer().greenBlue()
background.frame = self.view.bounds
self.view.layer.insertSublayer(background, atIndex: 0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func didTapSignOut(sender: AnyObject) {
GIDSignIn.sharedInstance().signOut()
}
}
and in the gui I have a button. When user clicks it then the session gets destroyed by this call: GIDSignIn.sharedInstance().signOut(). But, so far, nothing else happens and user is still in settings menu. I want to transfer him to my ViewController that contains log in form.
I tried to add the following code:
let sb = UIStoryboard(name: "Main", bundle: nil)
if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController {
window!.rootViewController = tabBarVC
}
but then the window is unresolved. How can I do it?
In the storyboard create a segue from the "Settings" ViewController to the "TabController" and set its identifier to "settingsToTabController". Then use the code self.performSegueWithIdentifier("settingsToTabController", sender: self) in the didTapSignOut function. I do not have a ton of experience with this so this may not be the best way of doing it, but it works fine for me.
If you want to do it the original way you posted using the window variable you need to grab an instance of that window instance from your delegate. You can get it by doing let window = UIApplication.sharedApplication().delegate?.window! and then setting the UIStoryboard to it as you did in your code above. Now your window object will not be unresolved.