首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何访问UIViewControllerRepresentable NavigationBar属性?

如何访问UIViewControllerRepresentable NavigationBar属性?
EN

Stack Overflow用户
提问于 2020-03-13 00:38:22
回答 2查看 4.2K关注 0票数 4

在SwiftUI中,如果您使用NavigationLink()将其转换为UIViewControllerRepresentable,那么您将如何在导航栏上添加按钮或更改标题属性。

这就是我现在正在做的:

代码语言:javascript
复制
import SwiftUI

/// Controls the actual action performed by the button upon taps.
struct CatagoryButton: View {

    @State var isPresenting :Bool = false

    var company : Company?
    var text : String

    var body: some View {

        NavigationLink(destination: UIKitWrapper(company: self.company, storyboardPointer: self.text)
            .navigationBarTitle(self.text)
            .edgesIgnoringSafeArea(.all),
                       isActive: self.$isPresenting,

                       label: {
            Button(action: {
                self.isPresenting.toggle()

            }){

                ZStack {

                    ButtonShadowLayer(text: text)

                    GradientBackground()
                        .mask(ButtonBaseLayer())

                    CircleAndTextLayer(text: text)
                }
            }
        })
    }
}

下面是我的可表示项的结构。

代码语言:javascript
复制
import SwiftUI

/// Wraps UIKIT instance in a representable that swiftUI can present.
struct UIKitWrapper: UIViewControllerRepresentable {

    //Specify what type of controller is being wrapped in an associated type.
    typealias UIViewControllerType = UIViewController

    //Company property passed from parent view. Represents the company the user selected from main view.
    private var company : Company

    //Determines which viewcontroller will be presented to user. This string corresponds to the name of the storyboard file in the main bundle.
    private var storyboardPointer : String

    init(company: Company?, storyboardPointer: String) {

        guard let company = company else {fatalError()}

        self.company = company
        self.storyboardPointer = storyboardPointer
    }

    func makeUIViewController(context: Context) -> UIViewControllerType {

        //Find user defined storyboard in bundle using name.
        let storyboard = UIStoryboard(name: storyboardPointer, bundle: .main)

        //Downcast returned controller to protocol AccessControllerProtocol. This step is required because we are not sure which storyboard will be accessed. Potential storyboard controllers that can be called all conform to this protocol. 
        //FIXME: Remove fatalError and create error enum asap.
        guard let viewController = storyboard.instantiateInitialViewController() as? AccessControllerProtocol else { fatalError() }

        //Assign user selected company object to instance property on incoming viewController.
        viewController.company = company

        //Return UINavigationController with storyboard instance view controller as root controller.
        return viewController
    }

    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {

    }
}

最后,这里是一个使用了可表示的类。

代码语言:javascript
复制
import UIKit

class OrdersViewController: UIViewController, AccessControllerProtocol {

    var company : Company!
    @IBOutlet var companyNameLabel : UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        setBackgroundColor()
        companyNameLabel.text = company.name
        self.navigationController?.navigationItem.rightBarButtonItems = [UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(self.tapRightBarButton))]
    }

    func setBackgroundColor(){

        let backgroundGradient = BackgroundGradientSetter()
        let viewWithGradient = backgroundGradient.setGradientToView(with: [DarkBlueHue_DEFAULT,LightBlueHue_DEFAULT], size: view.bounds)

        view.addSubview(viewWithGradient)
        view.sendSubviewToBack(viewWithGradient)
    }

    @objc func tapRightBarButton(){

    }
}

无论我做什么,这个按钮都不会出现。我不确定是否需要将其放在makeCoordinator()中,或者是否只是遗漏了什么。如果谁有真知灼见,请告诉我!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-13 02:00:01

在您的情况下,viewDidLoad上尚未提供navigationController,请按照以下演示模块中的说明进行尝试

经过测试,可与Xcode11.2/ iOS 13.2配合使用

代码语言:javascript
复制
class MyUIController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.navigationController?.navigationBar.topItem?.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(self.onAdd(_:)))
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // might be needed to remove injected item here
    }

    @objc func onAdd(_ sender: Any?) {
        print(">> tapped add")
    }
}

struct MyInjector: UIViewControllerRepresentable {
    func makeUIViewController(context: UIViewControllerRepresentableContext<MyInjector>) -> MyUIController {
        MyUIController()
    }

    func updateUIViewController(_ uiViewController: MyUIController, context: UIViewControllerRepresentableContext<MyInjector>) {
    }
}

struct DemoNavigationBarUIButton: View {
    var body: some View {
        NavigationView {
            MyInjector()
                .navigationBarTitle("Demo")
        }
    }
}

struct DemoNavigationBarUIButton_Previews: PreviewProvider {
    static var previews: some View {
        DemoNavigationBarUIButton()
    }
}
票数 -1
EN

Stack Overflow用户

发布于 2021-11-11 14:26:26

如果在viewDidLoad中不可用,请尝试在viewWillAppear()中调用setupNavigation()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60658388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档