Button action selector inside class - swift

I recently started developing in Swift (normally embedded C developer).
I want to create some button (later more than one) programmatically and change its label (just for practice).
For this I created a button class, which contains the button init and the callback function. My problem is that it seems like the #selector is not pointing to the instance of the button class the way I expected it will, so a button click does nothing. Can you tell me what I am doing wrong?
#objc class buttontest : NSObject{
let button = NSButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
#objc func printSomething() {
print("Hello")
self.button.title="TEST13"
}
func buttoninit() -> NSButton{
self.button.title="Test"
self.button.bezelStyle=NSButton.BezelStyle.rounded
self.button.target=self;
//button.action = Selector(ViewController.printSomething)
self.button.action = #selector(self.printSomething)
return self.button
}
}
class ViewController: NSViewController {
private lazy var redBox = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 100))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(redBox)
redBox.wantsLayer = true
redBox.layer?.backgroundColor = NSColor.red.cgColor
//button.init("Test12",self,Selector(printSomething())
let button = buttontest()
self.view.addSubview(button.buttoninit())
//self.view.addSubview(buttontest().buttoninit())
// Do any additional setup after loading the view.
}
override func loadView() {
self.view = NSView(frame: NSRect(x: 0, y: 0, width: NSScreen.main?.frame.width ?? 100, height: NSScreen.main?.frame.height ?? 100))
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}

The OK version:
#objc class buttontest : NSObject{
let button = NSButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
#objc func printSomething() {
print("Hello")
self.button.title="TEST13"
}
func buttoninit() -> NSButton{
self.button.title="Test"
self.button.bezelStyle=NSButton.BezelStyle.rounded
self.button.target=buttonX
self.button.action = #selector(buttontest.printSomething)
return self.button
}
}
let buttonX = buttontest()
class ViewController: NSViewController {
private lazy var redBox = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 100))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(redBox)
redBox.wantsLayer = true
redBox.layer?.backgroundColor = NSColor.red.cgColor
self.view.addSubview(buttonX.buttoninit())
}
}

Related

On mouse hover on NSButton Change Cursor (for OSX)

I made a subclass of NSButton
class Button: NSButton {
var cursor = NSCursor()
override func resetCursorRects() {
super.resetCursorRects()
addCursorRect(bounds, cursor: .pointingHand)
}
}
on my VC class i have added
let tempBtn = Button()
to call subclass but still no use. What am i doing wrong.
This works for me.
class ViewController: NSViewController {
class Button: NSButton {
override func resetCursorRects() {
super.resetCursorRects()
addCursorRect(bounds, cursor: .pointingHand)
}
}
override func viewDidLoad() {
super.viewDidLoad()
let button = Button(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
view.addSubview(button)
}
}

Swift access helper function view

I try to access the function "addNavBar()" from, my helper class, but when I run the emulator, no view is shown on HomeViewController.
Swift 4
HomeViewController.swift
class HomeController: UIViewController {
let NavBar = NavigationBarHelper()
override func viewDidLoad() {
super.viewDidLoad()
NavBar.addNavBar()
}
}
NavigationBarHelper.swift
class NavigationBarHelper: UIView {
func addNavBar() {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
self.addSubview(navBarView)
}
}
self in NavigationBarHelper is not the same object as the view in the view controller. Pass the VC's view as a parameter. There is no need to make NavigationBarHelper a subclass of UIView (in fact it could also be a struct).
class NavigationBarHelper {
func addNavBar(to view: UIView) {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
view.addSubview(navBarView)
}
}
please also stick to naming conventions
class HomeController: UIViewController {
let navBarHelper = NavigationBarHelper()
override func viewDidLoad() {
super.viewDidLoad()
navBarHelper.addNavBar(to: self.view)
}
Instead of creating an object every usage
let NavBar = NavigationBarHelper()
I think it's more robust to make it static like this
class NavigationBarHelper: UIView {
static func addNavBar(view:UIView) {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
view.addSubview(navBarView)
}
}
and call it directly without object creation
NavigationBarHelper.addNavBar(view: self.view)
A Better Alternative for this would be an extension so you don't have to create the special class for this
extension UIView {
func addNavBar() {
let rect = CGRect(x: 10, y: 70, width: 250, height: 100)
let navBarView = UIView(frame: rect)
navBarView.backgroundColor = UIColor.blue
self.addSubview(navBarView)
}
}
And in you UIViewController you can simply write this without creating an object of your helper.
self.view.addNavBar()

Prog created Buttons from class don't appear - Swift IOS

I'm trying to add a number of customClass buttons to my view automatically, based on the size of an array.
Created the class and called the appropriate method in the class, but nothing shows up. Debugging tells me that the method is called/executed as expected (3x).
When I add the function directly to the view controller it does work.
What am I missing here ???
ViewController code:
import UIKit
class ViewController: UIViewController {
let userArray: [String] = ["One","Two","Three"]
override func viewDidLoad() {
super.viewDidLoad()
for item in userArray {
CustomCheckBox().showNewButton()
}
}
.. Other stuff...
}
CustomButton class code:
{
import UIKit
class CustomCheckBox: UIButton {
let checkedImage: UIImage = UIImage(named:"chckbox_on")!
let uncheckedImage: UIImage = UIImage(named: "chckbox_off")!
var newButton: CustomCheckBox!
..... other functions (isChecked, buttonClicked, ..)
func showNewButton (){
newButton = CustomCheckBox (type: UIButtonType.Custom)
newButton.bounds = CGRect(x: 0, y: 0, width: 45, height: 45)
newButton.center = CGPoint(x: 40, y: 40)
newButton.addTarget(newButton, action: #selector(CustomCheckBox.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
newButton.isChecked=false
self.addSubview(newButton)
}
}
May consider restructuring your code like this
class CustomCheckBoxContainer: UIView {
var newButton: CustomCheckBox!
func showNewButton (){
newButton = CustomCheckBox (type: UIButtonType.custom)
newButton.bounds = CGRect(x: 0, y: 0, width: 45, height: 45)
newButton.center = CGPoint(x: 40, y: 40)
newButton.addTarget(newButton, action: #selector(CustomCheckBox.buttonClicked(_:)), for: UIControlEvents.TouchUpInside)
newButton.isChecked=false
self.addSubview(newButton)
}
}
class CustomCheckBox: UIButton {
let checkedImage: UIImage = UIImage(named:"chckbox_on")!
let uncheckedImage: UIImage = UIImage(named: "chckbox_off")!
//add here all your button functionality
}
and then change your view did load to something like this:
override func viewDidLoad() {
super.viewDidLoad()
for item in userArray {
let customCheckBoxContainer = CustomCheckBoxContainer()
customCheckBoxContainer.showNewButton()
self.view.addSubview(customCheckBoxContainer)
}
}
pass your current View as parameter of your function like this.
override func viewDidLoad() {
super.viewDidLoad()
for item in userArray {
CustomCheckBox().showNewButton(self.view)
}
}
Modify your custom UIButton function newButton like this
func showNewButton (currentView : UIView){
newButton = CustomCheckBox (type: UIButtonType.Custom)
newButton.bounds = CGRect(x: 0, y: 0, width: 45, height: 45)
newButton.center = CGPoint(x: 40, y: 40)
newButton.addTarget(newButton, action: #selector(CustomCheckBox.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
newButton.isChecked=false
currentView.addSubview(newButton)
}

Set delegate between custom uiview and custom uicontrol(swift)

import UIKit
public class SelectionItem: UIView {
var radioButtonController: SSRadioButtonsController
var stepper: KWStepper!
public init(){
let gcrRadioButton = SSRadioButton(frame: CGRect(x: 0, y: 100, width: 100, height: 50))
var decrementButton = UIButton(frame: CGRect(x: 400, y: 100, width: 50, height: 50))
var incrementButton = UIButton(frame: CGRect(x: 600, y: 100, width: 50, height: 50))
var countLabel = UILabel(frame: CGRect(x:500,y:100,width:50,height:50))
decrementButton.setImage(UIImage(named: "minus#2x.png"), forState: UIControlState.Normal)
incrementButton.setImage(UIImage(named: "plus#2x.png"), forState: UIControlState.Normal)
radioButtonController = SSRadioButtonsController(buttons: gcrRadioButton)
stepper = KWStepper(decrementButton: decrementButton, incrementButton: incrementButton)
stepper.delegate = self
stepper.valueChangedCallback = { [unowned self] stepper in
countLabel.text = String(format: "%.f", stepper.value)
}
super.init(frame: CGRectZero)
self.addSubview(gcrRadioButton)
self.addSubview(decrementButton)
self.addSubview(incrementButton)
}
required public init?(coder aDecoder: NSCoder) {
fatalError("KWStepper: NSCoding is not supported!")
}
}
Question: Error occur at stepper.delegate = self. Cannot assign value of type SelectionItem to type KWStepperDelegate. KWStepper is a custom uicontrol class. How can i set delegation between two of them.
You have the delegate set to self, but as written self does not implement the delegate protocol. It should be:
public class SelectionItem: UIView, KWStepperDelegate
Then your SelectionItem must implement the delegate protocol.

How can I draw a simple line?(OS X)

I tried this:
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var butt: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
#IBAction func buttPressed(sender: AnyObject) {
let myPath = NSBezierPath()
myPath.moveToPoint(CGPoint(x: 20, y: 20))
myPath.lineToPoint(CGPoint(x: 100, y: 100))
myPath.stroke()
}
}
It compiles and runs but doesn't draw anything when the button is clicked.
I tried setting the color: NSColor.redColor().set(), setting the width: myPath.lineWidth = 20 and using NSPoint instead of CGPoint but still the same thing happens. What is it that I'm missing?
Thank you for your answers in advance and sorry for the elementary question.
Try doing it inside drawRect (NSView):
import Cocoa
final class Line: NSView {
override func drawRect(dirtyRect: NSRect) {
let myPath = NSBezierPath()
myPath.moveToPoint(CGPoint(x: 20, y: 20))
myPath.lineToPoint(CGPoint(x: 100, y: 100))
myPath.stroke()
}
}
final class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
let line = Line(frame: frame)
view.addSubview(line)
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}