Swift: Should I Use `self` in ViewController Methods in Swift/iOS? [closed] - swift

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last month.
Improve this question
There are two way to call variables & methods in ViewController:
Case 1: Using self
import UIKit
class ViewController: UIViewController {
var count = 0;
override func viewDidLoad() {
super.viewDidLoad()
self.count = 1
self.myFunc()
}
func myFunc(){
...
}
}
Case 2: Access directly
import UIKit
class ViewController: UIViewController {
var count = 0;
override func viewDidLoad() {
super.viewDidLoad()
count = 1
myFunc()
}
func myFunc(){
...
}
}
Should I call variables and methods with the instance `self` in the scalable project at everywhere, or access them directly, as calling with the instance is a good way?
There is any difference between those two a function-calls in a class:
self.myFunc()
VS
myFunc()
It is working in both ways. It make any difference?

The best practice would be that we should avoid unnecessary calls with self.
It should be used when it's necessary like you want have a initialiser or a function with same name as your variable then you can use self to distinguish between both.
Another place would be the clousure.

Related

Multiply methods to property in Swift [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Greeting, Everyone!
I'm wondering how implement ability to multiply methods associated to certain class
For example I've got custom class of UITextField
and I want to configurate it any way I need.
How can I handle it to get result kinda myTextField.configure().addSomeExtraFeatures().andOneMoreMethod()
like in RxSwift viewModel.fetch().rx.asObservable.bind(to: ...
Can anyone show me some direction to resolving? :) Any clue, please ๐ŸŒ
Even how properly call this process will be useful ๐Ÿ™Š๐Ÿ™‰๐Ÿ™ˆ
Return self in every function and use #discardableResult attribute so no need to care about the return.
For more about #discardableResult: https://www.avanderlee.com/swift/discardableresult/
Your UITextField custom class should be like this.
class CustomTextField: UITextField {
#discardableResult
func configure() -> Self {
// Do your code here
return self
}
#discardableResult
func addSomeExtraFeatures() -> Self {
// Do your code here
return self
}
#discardableResult
func andOneMoreMethod() -> Self {
// Do your code here
return self
}
}
Usage:
Create an instance of CustomTextField and call function.
let customTextField: CustomTextField = CustomTextField()
customTextField.configure().addSomeExtraFeatures()

IOS Swift Protocol is not working or hitting breakpoint

I created a question a few days ago and was provided with protocol on how to solve an issue of passing data back and forth . I have also looked at some tutorials and have created a protocol but it is not working or even hitting the breakpoint from what I can see it should be working. I have created a protocol for my AVPlayer so that on tap it could get a new video but like i said it's not even hitting the breakpoint this is my code...
protocol CustomAVPLayerProtocol: class {
func reloadTabled(at index: Int)
}
class CustomAVPLayerC: AVPlayerViewController {
var delagate: CustomAVPLayerProtocol?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.delagate?.reloadTabled(at: 1)
for touch in touches {
self.delagate?.reloadTabled(at: 1)
print("Tapped")
// When I tap the AVPlayer this print statement shows
// So I know it is coming here
}
}
}
Now This is my second class/controller
class BookViewC: UIViewController, CustomAVPLayerProtocol {
override func viewDidLoad() {
super.viewDidLoad()
PlayVideo(250, "url")
}
func reloadTabled(at index: Int) {
print("This protocol method does not execute or hit breakpoint")
self.PlayVideo(250, "url")
}
func PlayVideo(MediaHeight: Float, MediaURL: String) {
let movieURL = URL(string: MediaURL)
videoCapHeight.constant = CGFloat(MediaHeight)
streamsModel.playerView = AVPlayer(url: movieURL!)
streamsModel.MyAVPlayer.player = streamsModel.playerView
streamsModel.MyAVPlayer.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
streamsModel.MyAVPlayer.showsPlaybackControls = false
streamsModel.MyAVPlayer.view.frame = VideoView.bounds
VideoView.addSubview(streamsModel.MyAVPlayer.view)
self.addChildViewController(streamsModel.MyAVPlayer)
streamsModel.playerView?.isMuted = false
streamsModel.MyAVPlayer.player?.play()
}
}
As I stated before it is not even hitting the breakpoint on BookViewC.reloadTabled as suggestions would be great
As per your code these are some minor mistakes which you can correct to make it work.
1. `weak var delagate: CustomAVPLayerProtocol?`
*Make a weak delegate to save it from retaining a strong reference cycle and memory leaks.*
2. Code Snippet:
func PlayVideo {
let customPlayer = CustomAVPLayerC()
customPlayer.delegate = self
}
in Your Second ViewController, You need to assign your delegate to an object / view controller to make ie respond to
NOTE: In case you require, you can make a super class that conforms the your protocol class, so that your every view controller conforms it automatically, you just need to assign an delegate to class on which you want to use it.
You have the foundation set up correctly but remember that classes are (mostly) just blueprints for instances. These classes are useless until you create instances of them because itโ€™s the instances that will do the work.
Therefore, simply pass one instance as the delegate of the other, which you can do here because you've correctly set up the protocol.
protocol CustomAVPLayerProtocol: AnyObject {
func reloadTabled(at index: Int)
}
class CustomAVPLayerC: AVPlayerViewController {
weak var delagate: CustomAVPLayerProtocol?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.delagate?.reloadTabled(at: 1)
for touch in touches {
self.delagate?.reloadTabled(at: 1)
print("Tapped")
}
}
}
class BookViewC: UIViewController, CustomAVPLayerProtocol {
override func viewDidLoad() {
super.viewDidLoad()
PlayVideo(250, "url")
}
func reloadTabled(at index: Int) {
PlayVideo(250, "url")
}
func PlayVideo(_ MediaHeight: Float, _ MediaURL: String) {
//
}
}
let book = BookViewC()
let layer = CustomAVPLayerC()
layer.delagate = book
Where you do this instantiation/delegation is up to you. Also, I know that a lot of people here use class to define protocols that only conform to classes, but Swift's documentation instructs us to use AnyObject.
Protocols are the most common means used by unrelated objects to communicate with each other. As per the above code, the communication did not seem to happen.
Your protocol declaration part seems alright. The problem exists in the secondViewController. I can see that you have not set the delegate to the object that's been created. Ideally, it has to be something like this:
Class BookViewC: UIViewController, CustomAVPLayerProtocol {
override func viewDidLoad() {
super.viewDidLoad()
PlayVideo(250, "url")
}
You need to the set the delegate here:
func PlayVideo {
let customPlayer = CustomAVPLayerC()
customPlayer.delegate = self //This makes the selector to respond
}

How to pass data back with no storyboard using Swift [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have 2 controllers. Let's call them A and B
Controller A is the main one and I have to check in viewWillAppear() if user exists.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let user = currentUser else {
let setupProfileViewController = SetupProfileViewController()
print("Current user empty")
let navigationController = UINavigationController(rootViewController: setupProfileViewController)
present(navigationController, animated: true, completion: nil)
return
}
}
Here user sees controller B and needs to fill data. On submit I validate all fields and create new User. Then I am dismissing B controller.
self.dismiss(animated: true) {
let matchViewController = MatchViewController()
matchViewController.currentUser = user
matchViewController.kolodaView.reloadData()
}
But what happens it A controller says there is no value in currentUser. I appreciate any advice on how to solve this.
The problem here is that
let matchViewController = MatchViewController()
matchViewController.currentUser = user
is a new instance of the class not the currently presented one , so setting user to it has no value , you have to use delegate or share your user via singleton class

Click event NSTextField OSX [duplicate]

This question already has answers here:
Click inside swift 2.2 OSX [closed]
(2 answers)
Closed 6 years ago.
I am having multiple textfields and I won't to invoke an action method if the user clicks on a textfield, this is what I currently have:
override func mouseDown(theEvent: NSEvent) {
}
for the click event.
This is the action to which it should reference when a textfield is pressed:
func myAction(sender: NSView)
{
print("aktuell: \(sender)")
currentObject = sender
}
For buttons it is working with the action and selector but this does not work for textfields...
button.action = #selector(myAction)
Please give examples only in swift, I know that there are plenty of examples in obj.-c. Thanks!
Got it working with that:
1) Create a subclass of NSTextField.
import Cocoa
class MyTextField: NSTextField {
override func mouseDown(theEvent:NSEvent) {
let viewController:ViewController = ViewController()
viewController.textFieldClicked()
}
}
2) With Interface building, select the text field you want to have a focus on. Navigate to Custom Class on the right pane. Then set the class of the text field to the one you have just created.**
3) The following is an example for ViewController.
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
func textFieldClicked() -> Void {
print("You've clicked on me!")
}
}

Swift Version 2 Bool [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm having trouble with creating an app in Swift2.
The App has an image of a wolf which changes every 0.4 seconds to reveal a running wolf.
However I have Bool errors in Swift 2 that I cannot fix.
I also have issues with declaring a void function.
Any help would be appreciated.
#IBAction func startRunnng(sender: UIButton)
{
tmrRun = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "update", userInfo: nil, repeats: true)
btnGo.userInteractionEnabled = NO;
btnStop.userInteractionEnabled = YES;
sliSpeed.userInteractionEnabled = NO;
}
#IBAction func stopRunnng(sender: UIButton)
{
tmrRun invalidate()
btnGo.userInteractionEnabled = YES;
btnStop.userInteractionEnabled = NO;
sliSpeed.userInteractionEnabled = YES;
}
void takeaBound
{
String *imageName = [NSString stringWithFormat:#"wolf%d.png", pic];self.imvWolf.image = [UIImage imageNamed:imageName];
pic += 1;
if (pic == 8)
pic = 0;
}
override func viewDidLoad() {
super.viewDidLoad()
pic = 0;
// Do any additional setup after loading the view, typically from a nib.
}
Boolean values in Swift are true and false, YES and NO is used in Objective C.
So in your stopRunning method for instance, you should write:
#IBAction func stopRunnng(sender: UIButton)
{
tmrRun invalidate()
btnGo.userInteractionEnabled = true
btnStop.userInteractionEnabled = false
sliSpeed.userInteractionEnabled = true
}
(sidenote, you don't need the ; in Swift either)
About the void function. In Swift you write the return type AFTER your method declaration, starting with a ->. Like so:
func takeABound(parametersWouldGoHere) -> ()
For a void method you can write () or Void or, as you'll often do, don't write anything at all.
func takeABound(parametersWouldGoHere)
As it says in "The Swift Programming Language" in the chapter about functions
Because it does not need to return a value, the functionโ€™s definition does not include the return arrow (->) or a return type.
You can read more about functions, booleans and the like in "The Swift Programming Language", there is a nice chapter called "A Swift Tour" that will introduce you to many of the basic things.
Hope that helps