UIView Extension does not work on app first launch - ios

I am using the following UIView extension:
https://github.com/snoozelag/GoneVisible
I have successfully downloaded the file and added the Swift file and I am using the extension to hide (gone method) and show (visible method) buttons on the navigation bar. When the app first opens, I call this extension in an attempt to hide certain buttons if the user is already logged in. However, this has not been working. Strangely, it DOES work and hides the buttons after I segue to a different view and go back.
Here is the code:
import UIKit
import Parse
class ViewController: UIViewController {
#IBOutlet weak var signUpButton: UIButton!
#IBOutlet weak var logInButton: UIButton!
#IBOutlet weak var myAccountButton: UIButton!
#IBOutlet weak var bigGame: UIImageView!
private func setUpPage(){
let currentUser = PFUser.current()
if currentUser != nil {
// Do stuff with the user
self.myAccountButton.visible()
self.signUpButton.gone()
self.logInButton.gone()
} else {
// Show the signup or login screen
self.myAccountButton.gone()
self.signUpButton.visible()
self.logInButton.visible()
}
}
override func viewDidLoad() {
setUpPage()
super.viewDidLoad()
self.navigationItem.hidesBackButton = true;
}
override func viewWillAppear(_
animated: Bool) {
setUpPage()
}
My question is, how can I get this extension to fire when the app is first opened?
Thanks a lot for your help :)

Don't forget to call super.viewWillAppear(...) when you override the inherited implementation.
This might solve your issue - but even if not it is correct to do it.
Update:
try calling setUpPage() only once and only after you call super.viewDidLoad()

Related

Unrecognized Selector sent to Instance:

New to this, so please bear with me. I have set up an IBAction to allow for a URL to open in Safari when the button is tapped. The URL opens successfully, but then I receive error in AppDelegate.swift: unrecognized selector sent to instance. When troubleshooting, I set up the same code and same IBAction in the initial view controller, and i did NOT get the error, and was able to return back to the app (from Safari) successfully. It seems this is happening only in one specific View Controller, which is not the initial VC. I'm hoping this is just a rookie and/or trivial mistake. Thanks for any help :)
import UIKit
class WeekDetailViewController: UIViewController {
#IBOutlet weak var lessonCompleteBtn: UIButton!
#IBOutlet weak var stackOButton: UIButton!
#IBOutlet weak var stackExchButton: UIButton!
#IBOutlet weak var redditButton: UIButton!
#IBOutlet weak var facebookButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func stackOButton(_ sender: Any) {
UIApplication.shared.open(URL(string: "https://www.google.com")! as URL, options: [:], completionHandler: nil)
}
}
Here is the problem:

Using shared classes for different views

I have an onboarding user flow:
Name -> Age -> Gender
Each of the screens shares the same structure:
Question (top)
Input (middle)
Continue (bottom)
I have a class OnboardingHelper.swift that creates a class to set the question box and continue button:
class UserOnboardingHelper{
var text: String
var questionbox: UIView
var viewController: UIViewController
var continueButton: UIButton
init(text: String, questionbox: UIView, viewController: UIViewController, continueButton: UIButton){
self.text = text
self.questionbox = questionbox
self.viewController = viewController
self.continueButton = continueButton
}
func setQuestionBox(){
//sets question box
}
func setContinueButton(){
//sets continue button
enableContinueButton()
addContinueButtonPath()
}
func enableContinueButton(){
//enables continue button
}
func disableContinueButton(){
//disables continue button
}
func addContinueButtonPath(){
//sets path of continue button based on which view
}
}
In each of the onboarding ViewControllers I am setting the class in ViewDidLoad():
class NamePageViewController: UIViewController, UITextFieldDelagate {
#IBOutlet weak var questionbox: UIView!
#IBOutlet weak var continueButton: UIButton!
#IBOutlet weak var inputLabel: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let namePageSettings = UserOnboardingHelper(text: "What is your name", questionbox: questionbox, viewController: self, continueButton: continueButton)
namePageSettings.setQuestionBox()
namePageSettings.setContinueButton()
inputLabel.delegate = self
if nameIsFilled {
namePageSettings.enableContinueButton()
} else{
namePageSettings.disableContinueButton()
}
}
}
The issue is that in the ViewController I textFieldDidEndEditing() function which needs to call the namePageSettings class from viewDidLoad()
func textFieldDidEndEditing(_ textField: UITextField){
if (textField.text?.empty)!{
//I want to call disableContinueButton() from UserOnboardingHelper
} else {
//I want to enable enableContinueButton() from UserOnboardingHelper
}
}
Trying to understand if:
The overall approach is correct and if not, what's the best way
If the above approach is in the right direction, how should disableContinueButton() and enableContinueButton() be called?
Thanks in advance! Sorry if the approach is really dumb - I'm still trying to wrap my head around classes.
You can have the view controller have a weak reference to the onboarding helper, so you can still call helper methods without creating a retain cycle.
In NamePageViewController, add a property:
weak var userOnboardingHelper: UserOnboardingHelper?
Then, in UserOnboardingHelper's initializer, add:
self.viewController.userOnboardingHelper = self
You can now call the onboarding helper's methods in the view controller:
userOnboardingHelper.disableContinueButton()
userOnboardingHelper.enableContinueButton()

Trigger button to change text in UITextView in swift3 xcode 8 ios 10

I'm new to xcode and am stuck on this problem, because after trying several sample code examples online, nothing works.
Could you help me figure out what the problem is?
My code below:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Writingboard: UITextView!
#IBOutlet weak var Talkbutton: UIButton!
#IBAction func TalkbuttonTapped(_ sender: AnyObject){
Talkbutton.setTitle("Tap to Stop", for: .normal)
Writingboard.text="talking"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Talkbutton.isEnabled=true
Writingboard.text="test the initializer"
}
}
you can try this bellow code you definetly get the output what you expected and make sure you connect the story board to your view controller class you button action and textfiled outlets can give IBActions and IBOutlets properly
output before not button tapped
After tapped the button

iOS 8.4 - iboutlet not populating in programmatically created view controllers

When loading a UIViewController programmatically in iOS 8.4 I am consistently seeing the IBOutlets registering as nil. This is causing crashes on any iOS 8.4 device. The exact same code runs smoothly on iOS 9 and 9.0.1. For reference, this is a snippet of the view controller
class B8AVPermissionsViewController: B8BaseViewController {
#IBOutlet weak var closeButton: UIButton!
#IBOutlet weak var cameraButton: UIButton!
#IBOutlet weak var microphoneButton: UIButton!
var delegate: B8PermissionRequestingDelegate? = nil;
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated);
NSLog("cameraButton: \(cameraButton)")
}
That prints out cameraButton: nil
The code that creates this looks like:
self.permissionViewController = B8AVPermissionsViewController()
self.permissionViewController!.delegate = self
dispatch_async(dispatch_get_main_queue(), {
self.presentViewController(self.permissionViewController!, animated: true, completion: nil)
})
What am I doing wrong?
The problem is that there's bug in iOS 8. Saying B8AVPermissionsViewController() in iOS 8 does not automatically load the associated nib. You need to work around this; for example, you could call init(nibName:bundle:) explicitly and tell it where the nib is.
The bug is fixed in iOS 9, which is why you're not seeing the same problem there.

how to instantiate/ show a TableViewController

I am struggling with this awful project for two weeks now and nothing seems to work. I have to do an app that loads some words from a server and presents them as pins on a map(MKView). I have to cluster the pins when the user zooms-out and for that I have used a this-party library written in Objective-C, but I also had to make a custom callout view with a button. When the user presses the said button the app should go to a TableViewController and here is my problem: I can't make it to do it. I have used before the "performSegueWIthIdentifier" and it worked very well, but now I get the error "there is no segue with '---' identifier". I know there are many other threads with this, but none of the solutions there work for me. Moreover, I have tried to instantiate the ViewController programmatically, but this does not work either because I get the "unexpectedly found nil..." and I don't know what to do any more.
I know I am doing something wrong, most probably how I call these functions, but I don't know what. This is what I have tried until now:
in the .xib file I have this:
import UIKit
class MarkerInfoView: MKAnnotationView {
#IBOutlet weak var theButton: UIButton!
#IBAction func readIt(sender: AnyObject) {
ViewController.goToArticles()
}
}
and in the ViewController:
class func goToArticles(){
ViewController().reallyGoToArticles()
}
I did this because I could not find another way to be able to call performSegueWithIdentifier or presentViewController
func reallyGoToArticles(){
println("let's go!")
let theArticlesSB = UIStoryboard(name: "Main", bundle: nil)
let vc = theArticlesSB.instantiateViewControllerWithIdentifier("theArticles") as! articlesViewController
self.presentViewController(vc, animated: true, completion: nil)
self.performSegueWithIdentifier("showArticles", sender: self)
}
I have uncommented both options just to show you.
I have uploaded the project here
Thank you very much!
Update
I forgot to mention that if I put the line
self.performSegueWithIdentifier("showArticles", sender: self)
in viewDidLoad it works
I had a look at your project and found your issue.
In MarkerInfoView.swift, you call ViewController.goToArticles() which is a class function:
class func goToArticles(){
ViewController().reallyGoToArticles()
}
This class function creates a NEW instance of ViewController which has nothing to do with the storyboard (and is not aware of segues).
You have to call self.reallyGoToArticles() from an instance method like
func goToArticles(){
self.reallyGoToArticles()
}
You have to manage to call the existing ViewController from your MarkerInfoView
EDIT: Here is how to achieve it
MarkerInfoView.swift
class MarkerInfoView: MKAnnotationView {
var vc: ViewController!
#IBOutlet weak var placePhoto: UIImageView!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var detailsLabel: UILabel!
#IBOutlet weak var theButton: UIButton!
#IBAction func readIt(sender: AnyObject) {
vc.goToArticles()
}
}
ViewController.swift
func mapView(mapView: MKMapView!, didSelectAnnotationView annotation: MKAnnotationView!)
{
if let pin = annotation.annotation as? CustomPointAnnotation{
if var infoView = UIView.viewFromNibName("MarkerInfoView") as? MarkerInfoView {
infoView.nameLabel.text = pin.theTitle
infoView.detailsLabel.text = pin.theDetails
infoView.vc = self
infoView.center = CGPointMake(self.view.bounds.width/2, self.view.bounds.height/2)
self.view.addSubview(infoView)
} else {
}
}
}
func goToArticles(){
self.reallyGoToArticles()
}

Resources