네이티브 뷰 사용하기 - IOS(swift)

이번 글에서는 flutter가 아닌 native view를 사용하는 방법에 대해서 알아보도록 하겠다.

우선 네이티브 코드에 대해서 자세히 알지 못하여 코드만 작성할 예정이다.

Swift

AppDelegate.swift

Platform Channel을 사용할 때 채널 등록을 하듯이 AppDelegate 객체 안에 아래 코드를 추가해준다.

withId 값에 넣어준 값이 flutter 코드에서 호출해서 가져오는 키 값이다.

 let factory = TestFactory()
 self.registrar(forPlugin: "TestViewPlugin")?.register(factory, withId: "test-type")

FLNativeTestFactory.swift

위에서 선언한 factory 객체를 아래 와 같이 생성해주면 된다.

class TestFactory: NSObject, FlutterPlatformViewFactory{
    private var testView: TestView?
    private var messenger: FlutterBinaryMessenger?
    
    override init(){
        super.init()
    }
    
    init(messenger: FlutterBinaryMessenger) {
        self.messenger = messenger
        super.init()
    }

    func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        
        self.testView = TestView(
            frame: frame,
            viewIdentifier: viewId,
            arguments: args,
            binaryMessenger: messenger)
        return testView ?? TestView(
            frame: frame,
            viewIdentifier: viewId,
            arguments: args,
            binaryMessenger: messenger)
    }
}

FLNativeTestView.swift

이어서 View 부분을 담당할 객체를 생성한 후 실제 보여줄 뷰를 작성할 코드를 넣어준다.

class TestView: NSObject, FlutterPlatformView{
    private var returnView: UIView?
    var nativeLabel = UILabel()
    
    override init() {
        returnView = UIView()
        super.init()
    }
    
    init(
        frame: CGRect,
        viewIdentifier viewId: Int64,
        arguments args: Any?,
        binaryMessenger messenger: FlutterBinaryMessenger?
    ) {
        returnView = UIView()
        super.init()
        createNativeView(view: returnView!, args: args)
    }
    
    func view() -> UIView {
        return returnView!
    }
    
    func createNativeView(view _view: UIView, args: Any?){
        _view.backgroundColor = UIColor.red
        nativeLabel.text = "Native TestView"
        nativeLabel.textColor = UIColor.white
        nativeLabel.textAlignment = .center
        nativeLabel.frame = CGRect(x: 0, y: 0, width: 180, height: 48.0)
        nativeLabel.translatesAutoresizingMaskIntoConstraints = false
        _view.addSubview(nativeLabel)
        nativeLabel.centerXAnchor.constraint(equalTo: _view.centerXAnchor).isActive = true
        nativeLabel.centerYAnchor.constraint(equalTo: _view.centerYAnchor).isActive = true
    }
}

Flutter

NativeViewScreen.dart

Scaffold로 감싼 후 네이티브 뷰를 바디에 UiKitView 객체를 사용하면 끝이다.

viewType 안에 값을 swift에서 연결해준 id 값과 동일하게 넣어주면 된다.

UiKitView안에 자식 위젯은 정해줄 수 없지만 해당 객체의 부모 위젯으로 flutter widget을 사용하여도 된다.

  body: UiKitView(
        viewType: 'test-type',
        layoutDirection: TextDirection.ltr,
      ),

마무리

네이티브 뷰를 고려해본 이유는 flutter 에서 Ios Status Bar 터치시 스크롤을 상단으로 올려주는 기본 기능이 내장되어 있기에 네이티브 뷰 자식으로 flutter widget을 사용하려고 했지만 UiKitView에 자식 속성을 넣을 수 없어서 포기했다.

다음 시간엔 swift 코드에 status bar 터치 이벤트를 감지하는 event channel을 연결해서 primaryScrollController가 없이도 scrollToTop기능을 사용할 수 있는 방법을 구현할 예정이다.

primaryScrollController 사용시 스크롤 제어에 한계가 있고, sentry 에러 로그 시스템에도 스크롤 관련 로그가 많이 감지되고 있어 더 이상 사용을 하지 않으려고 한다.

좋은 방법이 있다면 공유해주세요 !

profile
Flutter Developer

0개의 댓글