이번 글에서는 flutter가 아닌 native view를 사용하는 방법에 대해서 알아보도록 하겠다.
우선 네이티브 코드에 대해서 자세히 알지 못하여 코드만 작성할 예정이다.
Platform Channel을 사용할 때 채널 등록을 하듯이 AppDelegate 객체 안에 아래 코드를 추가해준다.
withId 값에 넣어준 값이 flutter 코드에서 호출해서 가져오는 키 값이다.
let factory = TestFactory()
self.registrar(forPlugin: "TestViewPlugin")?.register(factory, withId: "test-type")
위에서 선언한 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)
}
}
이어서 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
}
}
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 에러 로그 시스템에도 스크롤 관련 로그가 많이 감지되고 있어 더 이상 사용을 하지 않으려고 한다.
좋은 방법이 있다면 공유해주세요 !