Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selectors in SwiftUI

Tags:

ios

swiftui

I'm trying to use 3rd party libraries that are created for UIKit in SwiftUI, for example, the BetterSegmentedControl library (https://github.com/gmarm/BetterSegmentedControl) requires a Selector witch takes an objc function to handle users input.

is there even a way of handling this in SwiftUI?

struct ContentView : UIViewRepresentable {
    func makeUIView(context: Context) -> BetterSegmentedControl {
        BetterSegmentedControl()
    }


    func updateUIView(_ view: BetterSegmentedControl, context: Context) {
        let control = BetterSegmentedControl(
            frame: CGRect(x: 0, y: 0, width: 300, height: 44),
            segments: LabelSegment.segments(withTitles: ["One", "Two", "Three"],
                                            normalTextColor: .lightGray,
                                            selectedTextColor: .white),
            index: 1,
            options: [.backgroundColor(.darkGray),
                      .indicatorViewBackgroundColor(.blue)])

        view.addSubview(control)

        @objc func controlValueChanged(_ sender: BetterSegmentedControl) {

        }

        control.addTarget(self, action: #selector(controlValueChanged(_:)), for: .valueChanged)
        view.addSubview(control)

    }
}

for this code there are 2 errors:

@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes


Argument of '#selector' cannot refer to local function 'controlValueChanged'
like image 521
SinaMN75 Avatar asked Jul 03 '19 09:07

SinaMN75


2 Answers

I've ended up adding a helper class:

struct MainView: View {

let helper = MainViewHelper()

// somewhere, sometimes...
vc.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self.helper, action: #selector(self.helper.closeAction))

}

class MainViewHelper {
  @objc func closeAction() {
    // whatever
  }
}
like image 134
orkenstein Avatar answered Sep 28 '22 02:09

orkenstein


Well, as the error tells you, you cannot use objc on structs. So I guess you can always create a helper class.

I faced a similar problem when listening to keyboard show and hide notifications in a different question. Here's my answer. If you scroll down to the class KeyboardGuardian, you'll see that I am using objc there.

It's a starting point...

https://stackoverflow.com/a/56721268/7786555

like image 22
kontiki Avatar answered Sep 28 '22 02:09

kontiki