Swift: NSPopUpButtonCell in NSTableHeaderCell - swift

I cannot for the life of my figure out how to get an NSPopUpButtonCell to work in a NSTableHeaderCell. I've tried to implement the solution here: Getting duplicate header button cell in NSTableView when using NSPopUpButtonCell but it seems some of the methods there aren't available in Swift, specifically performClickWithFrame on the headerCell.
I've managed to get the popup button to draw in the header like this:
class DropDownHeaderCell: NSTableHeaderCell {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(textCell aString: String) {
super.init(textCell: aString)
}
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
let buttonCell = NSPopUpButtonCell(textCell: "", pullsDown: true)
buttonCell.addItemsWithTitles(["Item1", "Item2", "Item3"])
buttonCell.drawWithFrame(cellFrame, inView: controlView)
}
}
Whenever I try to click on the button it selects the header cell instead. How do I get it so that my click register on the button and not the header?

Related

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?

Change IBOutlet button's type

I'm trying to achieve something I'm not sure if it's doable. I have a xib for UITableViewCell that has a UIButton in it with custom class assigned in storyboard i.e MainButtonSuperClass. In UITableViewCell.swift outlet is connected like following,
#IBOutlet weak var button: MainButtonSuperClass!
Many different controllers are configuring this TableViewCell but button's UI will be different for all those controllers as defined in subclass i.e.
final class MainButtonSubClass: MainButtonSuperClass {
override func configure(){//different style of button }
}
How can I achieve this? so far I have tried following,
let button: MainButtonSuperClass = MainButtonSubClass()
button.configure()
cell.button = button
But this doesn't pick the style
EDIT:
//tableview cell
class TableViewCell: UITableViewCell {
#IBOutlet weak var button: MainButtonSuperClass!
}
//Controller A wants default style of superclass (MainButtonSuperClass)
func configureButton(buttonCell: TableViewCell) {
buttonCell.button.configure() //works
}
//Controller B wants different style of subclass (MainButtonSubClass)
func configureButton(buttonCell: TableViewCell) {
let button: MainButtonSuperClass = MainButtonSubClass()
button.configure()
cell.button = button // doesn't work or adopts the style
}
//Custom button's classes
final class MainButtonSuperClass: UIButton {
override func configure(){//styled button }
}
final class MainButtonSubClass: MainButtonSuperClass {
override func configure(){//different style of button }
}
Ok understand, let's try this
class CustomClass: UIButton {
class Type1Class: UIButton {
// Do all the setup here
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class Type2Class: UIButton {
// Do all the setup here
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}
Then you can initialize it with the following:
#IBOutlet weak var button: CustomClass.Type1Class!
Hope it helps!
I found the solution. I will not use IBOutlet but just a property of UIButton that I will change dynamically with factory method. With IBOutlet it's not possible.

How to Observer UITexFiled startEditing and EndEditing in its SubClass?

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() {
}
}

How to sub class custom view controller in swift? [duplicate]

This question already has an answer here:
Adding subclass to Storyboard crashes
(1 answer)
Closed 5 years ago.
I have custom view controller which contains TableView. I have another view controller which extends custom view controller.
How can I pass the TableView from subclass to super view?
Here is the parent view controller:
class CustomViewController: CustomNavigationController, UISearchResultsUpdating,UITableViewDelegate, UITableViewDataSource {
var query: String = "male"
var tableView: UITableView!
convenience init(tableView: UITableView, query: String){
self.init()
self.tableView = tableView
self.query = query
}
And this is what I did in sub class:
class GirlsViewController: CustomViewController {
#IBOutlet weak var tableViewObj: UITableView!
convenience init() {
self.init(nibName:nil, bundle:nil)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tableView = tableViewObj
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The application crash at this line fatalError("init(coder:) has not been implemented")
Just do what the error message says: You need to implement init?(coder.
The basic implementation is to call super and do the same things as in init(nibName
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
tableView = tableViewObj
}

How to disable user interaction of NSTextView?

In Cocoa Touch, you can disable user interaction of a text view like this:
let textView = UITextView()
textView.isUserInteractionEnabled = false
But in Cocoa, NSTextView has no such easy API to use.
So what's the proper way to disable NSTextView user interaction?
You can disable its' editable by:
textView.isEditable = false
And its' selectable by:
textView.isSelectable = false
However, when you disable both of them. This textView still will intercept Mouse-down event, which is different from isUserInteractionEnabled .
So, for now, to enable click-through, my solution is subclassing a NSTextView and override its' hitTest:
class TextView: NSTextView {
override func hitTest(_ point: NSPoint) -> NSView? {
return nil
}
}
An encapsulated way is here
class StaticTextView: NSTextView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
override init(frame frameRect: NSRect, textContainer container: NSTextContainer?) {
super.init(frame: frameRect, textContainer: container)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func hitTest(_ point: NSPoint) -> NSView? {
return nil
}
}