access a textfield from a nsobject class - swift

I am trying to access a textfield from a nsobject class. It's causing a runtime error of can't find txt in scope.
I tried having class coredata be inherited but that does not work. I don't really know what to do next. I may have to use parameter to pass the textfield but I am not sure how that would work.
import UIKit
class ViewController: UIViewController {
var txt = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
class coreDataHandler : NSObject {
class func saver(){
txt.text = "d"
}
}

Related

Delegate Method is not called in UIButton class

I have a UIbutton class - from which I would like to call an 'adjust constraints' method after the user makes changes on the setting screen. I have created some protocols and all seems in order but it is not calling the method from the subview UIButton after the user closes the Setting Screen.
I have tried some of the other solutions here - that hasn't worked and I think it might be because I am using a UIButton class and I can't reinstantiate it, or call the instantiation? Either way, it never calls the method from the delegate.
Is using protocols the right way to solve this problem and if so, what am I missing?
Basically I have 3 files; the MainVC which I set as my first delegate (it gets triggered from my SettingScreenVC when user is done making changes to Setting Screen):
class MainVC: UIViewController, SettingScreenDelegate {
weak var numButtonDelegate: Buttons_Numeric?
func settingSetButtonConstraints() {
numButtonDelegate?.setupButtonConstraints()
}
}
Then in my Setting Screen I call the MainVC after the user made some changes to their settings:
class MainVC: SettingScreenVC {
weak var delegate: SettingScreenDelegate?
func closeSettings() {
delegate?.settingSetButtonConstraints()
}
}
Then in my Buttons_Numeric class I declare the function and the UIButton class delegate:
protocol numButtonDelegate: class {
func setupButtonConstraints()
}
class Buttons_Numeric: UIButton, numButtonDelegate {
weak var numButtonDelegate: Buttons_Numeric?
required init(coder aDecoder:NSCoder) { super.init(coder: aDecoder)!}
override init(frame:CGRect) {super.init(frame: frame)
self.numButtonDelegate = self
setupButtonConstraints()
}
override func awakeFromNib() {
self.numButtonDelegate = self
setupButtonConstraints()
}
func setupButtonConstraints() {
//SET UP CONSTRAINTS
}
}
Ok so couple of things you need to understand about delegates:
if you create a delegate, you need to conform to the delegate somewhere.
the conforming class should be assigned to the instance of the delegate.
With that in mind lets try to fix the code:
first the settings screen:
protocol SettingScreenDelegate: class {
func settingSetButtonConstraints()
}
class SettingScreenVC {
weak var delegate: SettingScreenDelegate?
func closeSettings() {
delegate?.settingSetButtonConstraints()
}
}
So far so good now the mainScreen should conform to the SettingScreenDelegate and be assigned to its delegate:
class MainVC: UIViewController, SettingScreenDelegate {
weak var button: Buttons_Numeric!
func openSettingsScreen() {
let settingsScreen = ... // the setting screen instanciation
settingsScreen.delegate = self // the MainVC
}
func settingSetButtonConstraints() {
self.button.setupButtonConstraints()
}
}
Now for the last step, the MainVC should have an instance of the button, then the only thing we need to do is call the function 'setupButtonConstraints' from the MainVC which means we do not need the delegate at the button.
class Buttons_Numeric: UIButton {
required init(coder aDecoder:NSCoder) { super.init(coder: aDecoder)!}
override init(frame:CGRect) {super.init(frame: frame)
setupButtonConstraints()
}
override func awakeFromNib() {
setupButtonConstraints()
}
func setupButtonConstraints() {
//SET UP CONSTRAINTS
}
}
You need to assign a value to the delegate variable. I would do it like this if the answer is always self
class Example: SomeDelegate {
lazy var someDelegate: SomeDelegate? = self
}
Otherwise you'll want to do it in the class' initializer or ViewDidLoad.

My delegate function is not being called in Swift

I have a main view titled NoteTakerViewController. I have a weatherGetterController class with a protocol that returns 5 days of weather with a protocol function called getMyWeather. However the protocol function is not being called that returns the weather data to NoteTakerViewController. I am certain I have everything set up correctly with the delegates but perhaps I do not.
This is really not a duplicate of Swift Delegate Not Being Called as the solution on that page did not work.
Any help you could provide would be great.
Here's the relevant code snippets:
My weatherGetterController class:
protocol WeatherGetterControllerDelegate {
func getMyWeather(weather: [FiveDayForecast])
}
class WeatherGetterController: UIViewController, CLLocationManagerDelegate {
var weatherGetterDelegate: WeatherGetterControllerDelegate?
And in the WeatherGetterController "getWeather" function call. The line
self.weatherGetterDelegate?.getMyWeather(weather: myForecast)
is not being called.
func getWeather() {
...
getNetWeather { (fetchedInfo) in
if let fetchedInfo2 = fetchedInfo {
//self.updateUI(mainWeather: fetchedInfo2)
//need to call delegate here
let myForecast = self.figureFive(weather: fetchedInfo2)
//return the forecast
print(myForecast)
self.weatherGetterDelegate?.getMyWeather(weather: myForecast)
}
}
Finally the function implementation in NoteTakerViewController:
class NoteTakerViewController: UIViewController, ..., UITextFieldDelegate, WeatherGetterControllerDelegate
func getMyWeather(weather: [FiveDayForecast]) {
print("get my weather")
print(weather)
}
Through debugging I can see that "weatherGetterDelegate" is set to nil and I don't know why.
Thanks
First you need to make WeatherGetterController a property in NoteTakerViewController or a local variable where you call it but I will use the first option.
class NoteTakerViewController: UIViewController, ..., WeatherGetterControllerDelegate {
var weatherGetterController: WeatherGetterController?
//...
func viewDidLoad() {
//....
weatherGetterController = WeatherGetterController()
weatherGetterController?.delegate = self
}
//And then in some other part of your code you do
func someFunc() {
self.weatherGetterController?.getWeather()
I am curious why WeatherGetterController is define to be a viewcontroller, is that really correct?
class WeatherGetterController: UIViewController, CLLocationManagerDelegate {
Personally I would remove that part
class WeatherGetterController: CLLocationManagerDelegate {
Put this in init of WeatherGetterController
public weak var weatherGetterDelegate: WeatherGetterControllerDelegate?
/* if you are not initializing it anywhere else
and if you are initializing it anywhere else then make sure you are
initializing WeatherGetterController there too and then put delegate
of WeatherGetterController to NoteTakerViewController object
else write the below code */
var model = NoteTakerViewController()
public override init() {
self. weatherGetterDelegate = model
}

What's the best way to watch the change of data in Cocoa

I have a singleton to store some global data for my macOS app, one of my ViewController keeps modifying data. I want to simultaneously show the changes in a View, which is related to another ViewController. what 's the best way to do this?
Global Data:
final class AppData {
static var logs: [LogData] = []
}
ViewController 1:
class FirstViewController: NSViewController {
AppData.logs.append(newLogData)
}
ViewController 2:
class SecondViewController: NSViewController {
// what's the best way to simultaneously watch the change of AppData.logs?
}
If your App is planned to be macOS only you can use a NSObjectController. This is definitively the easiest approach and you can do most of the configuration in Interface builder. It works internally with bindings. In case of an array you want to observe, you would use a NSArrayController.
One way is to use the notificationcenter
In viewcontroller2 add:
override func viewDidLoad() {
super.viewDidLoad()
notificationCenter.default.addObserver(self,
selector: #selector(view1DidChange),
name: "view1DidChange",
object: nil
)
}
#objc private func view1DidChange(_ notification: Notification) {
// Do something
}
In viewcontroller1 add
notificationCenter.default.post(name: "view1DidChange", object: self)
This can be repeated in every class, that should listen.
Here i am sharing the Delegate & Protocol approach to achieve this functionality.
final class AppData {
static var logs: [LogData] = []
}
protocol FirstViewControllerDelegate {
func ViewControllerDelegate(appData:[LogData])
}
class FirstViewController: NSViewController {
var delegate:FirstViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
AppData.logs.append(newLogData)
self. delegate?.ViewControllerDelegate(appData: AppData.logs)
}
}
class SecondViewController: NSViewController,FirstViewControllerDelegate {
var firstViewController:FirstViewController = FirstViewController()
override func viewDidLoad() {
self.firstViewController.delegate = self
}
func ViewControllerDelegate(appData:[LogData]){
//Do Update the UI
}
}

Swift Function Algorithm

when I run this method in my project, the "name" variable is empty
Example :
import UIKit
class userDetail {
static var name : String?
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func OK(sender: UIButton){
getUserDetail()
print(userDetail.name)
// The first click is nil, the second click is print "test". How can I solve this problem?
}
func getUserDetail() {
userDetail.name = "test"
}
}
You have to instantiate it, as most of the comments suggest.
You need to do:
var userInfo = userDetail()
userInfo.name = "Test"
print(userInfo.name!)
As others suggested, you need to make class names (userDetail) capital. This is because class names start with class names. (UserDetail)

ios 8 and Swift: call a function in another class from view controller

I want to touch a button in ViewController and run a simple function in a custom class. No parameters needed. Code is basically:
class MyClass: UIView {
//init function is here
//other setup stuff
...
func SetFocus() {
//I want to set the camera focus to infinity.
var error: NSErrorPointer = nil
var pos: CFloat = 1.0
captureDevice!.lockForConfiguration(error)
captureDevice!.setFocusModeLockedWithLensPosition(pos, completionHandler: nil)
captureDevice!.unlockForConfiguration()
}
}
and in ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet var myClass: MyClass!
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.
}
#IBAction func myButton(sender: UIButton) {
myClass.SetFocus()
}
}
I've tried everything I can think of (new at Swift) and the app either crashes or the function I'm calling doesn't run. Everything else in MyClass works OK.
Try to delete the #IBOutlet from before MyClass.
var myClass : MyClass!
You can also try this:
var myClass : MyClass! = MyClass()
From the looks of it, however, everything you are doing in setFocus() in MyClass, can easily be recreated in the ViewController.
Try this
#IBAction func myButton(sender: UIButton) {
var ClassViewController = self.storyboard.instantiateViewControllerWithIdentifier("StoryboardID") as! UIViewController
ClassViewController.MyFunction()
}