How to Observer UITexFiled startEditing and EndEditing in its SubClass? - swift

How to observer in UITexFiled sub class ,if current textField is started Ending or Ended Editing in same class .
if I'll write self.delegate = self then my ViewController UITextField method will not called .
I want to make a UITexFiled SubClass when every editing is started then I'll scale up the textFiled ,and when editing is done then UITexField will be back to normal size . but I want to handle from my subclass not to write logic every UITexFeildDelegate in all ViewController Please help me .

You can add targets for the specific events
class MyTextField: UITextField {
override init(frame: CGRect) {
super.init(frame:frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
self.addTarget(self, action: #selector(didBegin), for: .editingDidBegin)
self.addTarget(self, action: #selector(didEnd), for: .editingDidEnd)
}
#objc func didBegin() {
}
#objc func didEnd() {
}
}

Related

how to customize a label when is not in viewdidload?

I have those variables in collectionviewcell file and I want to change label background and cornerradius but that file doesnt have a viewdidload how can I do that . Thanks for helps.
UIView subclasses do not have a viewDidLoad method, instead you use the view's initializer:
class MyCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
layoutUI()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
layoutUI()
}
private func layoutUI() {
label.layer.cornerRadius = 5
label.backgroundColor = .blue
}
}

Adding a ViewController into a UICollectionviewcell

I would like to embed a ViewController inside a UICollectionView cell, I tried to search on the internet but I haven't found anything applicable to my case.
I've done this so far,
this is the View Controller:
class ExploreViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemGreen
}
}
This is the collectionViewCell:
class ExploreCollectionViewCell: UICollectionViewCell {
let exploreViewController = ExploreViewController()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(exploreViewController.view)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Basically I'm instantiating a ViewController inside the cell and displaying its view;
I don't think this is actually the best thing to do but honestly I don't know how to implement it in a different way.
The best thing would be to actually embed the viewController inside the cell, do you know how could I do it?

Detect if custom UITextField has a text value

I created a custom text field, a class that extends a UITextField, how can I know if that UITextField has a value, I already tried the shouldChangeCharactersIn but nothing happened.
This is my code for my custom UITextField Class
#IBDesignable class CustomTextField: UITextField {
override init(frame: CGRect) {
super.init(frame: frame)
loadContent()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadContent()
}
...
}
I want to print "the textfield is blank" if the UITextField is blank or if the user removed the value in it, and "the textfield has content" if there's a value in it or if the user add a value in it.
You just need to add a target to your text field for UIControl.Event .editingChanged
override func willMove(toSuperview newSuperview: UIView?) {
addTarget(self, action: #selector(editingChanged), for: .editingChanged)
}
And use UIKeyInput method hasText to check if your field is empty or not:
#objc func editingChanged(_ textField: UITextField) {
print("the textfield " + (hasText ? "has content" : "is blank"))
}

Loading Nib file as inputAccessoryView

I have a Nib file. Image attached. I would like this Nib file as the inputAccessoryView. Reason being accessoryView doesn't adhere to Safe Area on iphoneX. grrrr!
I have set up my Nib file as per this tutorial...
https://medium.com/code-with-rohit/inputaccessoryview-and-iphonex-7b5547fe98da
How do I correctly get this Nib file inside the inputAccessoryView?
I have my custom Class "AccessoryView" as the File's Owner. From here I struggle.
Any help as always highly appreciated.
UPDATE:
I've removed the File Owner and added the class to the top View.
In my AccessoryView Class I have
override init(frame: CGRect) { // for using CustomView in code
super.init(frame: frame)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) { // for using CustomView in IB
super.init(coder: aDecoder)
if self.subviews.count == 0 {
self.commonInit()
}
}
class func instanceFromNib() -> UIView {
return UINib(nibName: "AccessoryView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! UIView
}
private func commonInit() {
guard let container = accessoryViewContainerView else { return }
container.frame = self.bounds
container.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.addSubview(container)
}
}
But it gave me the below effect:
I then add the view to the inputAccessoryView as such:
override var inputAccessoryView: UIView? {
get {
return AccessoryView.instanceFromNib()
}
}
As you can see it has added the subViews but the constraints are all off.

How to Pass extra parameters to a custom UIView class for initialization in swift

I'm trying to write a class that is of type UIView, but on initialization I want it to take an extra parameter, but I can't figure out how to get around the UIView needing its params instead. Any help is much appreciated!
class MenuBar: UIView {
let homeController: HomeController
init(controller: HomeController){
homeController = controller
super.init()
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
In the ViewController I'm initializing it like this:
let menuBar: MenuBar = {
let mb = MenuBar(controller: self)
return mb
}()
Try this.
class MenuBar: UIView {
let homeController: HomeController
required init(controller: HomeController){
homeController = controller
super.init(frame: CGRect.zero)
// Can't call super.init() here because it's a convenience initializer not a desginated initializer
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
From my experience this is what works best if you want to have custom initialiser for UIView:
class CustomView : UIView {
private var customProperty: CustomClass
required init(customProperty: CustomClass) {
super.init(frame: .zero)
self.customProperty = customProperty
self.setup()
}
required override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
fileprivate func setup() {
//Here all custom code for initialisation (common for all creation methods)
}
}
This approach allows you to keep common initialisation code regardless of method of creating the view (both storyboard and code)
That's about creating UIView properly.
Additionally I would recommend to avoid passing UIViewController to UIView - I think you are trying to solve some problem in a wrong way.
Much better ways to communicate between those two is to use delegate or closure - but that's a bit off-topic - maybe you can create another question about why you want to pass it like this.