如何用子视图卸载uiView

Posted

技术标签:

【中文标题】如何用子视图卸载uiView【英文标题】:How to unload uiView with subview 【发布时间】:2021-07-22 01:15:27 【问题描述】:

我很难弄清楚如何卸载我的 UIView。

这就是我正在做的事情。

我有一个 UI 视图类

@protocol JitsiViewDelegate <NSObject>

@optional
- (void)meetingEnded;
@end

@interface JitsiView : UIView

@property (nonatomic, nullable, weak) id<JitsiViewDelegate> delegate;
- (void)join:(JitsiMeetingConfig*)config;
@end

连接 (.m) 文件如下所示

- (void) join:(JitsiMeetingConfig*)config

    RCTBridge *bridge = [[Jitsi sharedInstance] getReactBridge];
  rootView = [[RNRootView alloc] initWithBridge:bridge
                                moduleName: @"JitsiTest"
                              initialProperties: [self getInitialProperties:config]];
  rootView.backgroundColor = self.backgroundColor;
  // Add rootView as a subview which completely covers this one.
          [rootView setFrame:[self bounds]];
        rootView.autoresizingMask
            = UIViewAutoresizingFlexibleWidth
                | UIViewAutoresizingFlexibleHeight;
    [self addSubview:rootView];

在上面

RNRootView 是this

RCTBridge 将是this

我在一个快速的项目中使用它

import UIKit
import JitsiSdk;

class ViewController: UIViewController 
    @IBOutlet weak var videoButton: UIButton?
    fileprivate var JitsiView: jitsiView?
    fileprivate var config: JitsiMeetingConfig?
    
    override func viewDidLoad() 
        super.viewDidLoad()

       //Config (removed code intentionally as it wasn't realvent) 

    
    
    @IBAction func joinMeeting(_ sender: Any) 
                let jitsiView = JitsiView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height:self.view.bounds.size.height ))
                .delegate = self
                self.jitsiView = jitsiView;
                self.view.addSubview(jitsiView)
                jitsiView.join(config);
    
    
    fileprivate func onMeetingEnded() 
            if(jitsiView != nil) 
                jitsiView?.removeFromSuperview()
            
        



extension ViewController: JitsiViewDelegate 
    func meetingEnded() 
        onMeetingEnded()
    

在 meetingEnded 上,我想删除 JitsiView 并在加载 JitsiMeetView 之前显示我的视图控制器中的内容,但当前代码抛出以下错误

'NSInternalInconsistencyException',原因:'修改 布局引擎不得在其后的后台线程中执行 已从主线程访问。'

有人可以帮助我了解为什么我会收到此错误以及如何解决它吗?

【问题讨论】:

我不太确定,但您是否将代表与视图层次结构混淆了?首先,为什么不简单地 present 一个视图控制器全屏它的根视图是 JitsiView?,然后简单地关闭它? (你标记了这个 [ios],所以我假设它不是你试图在 macOS 上运行的东西。)接下来,你为什么要添加/删除视图?最后,该错误实际上表明您正在从后台线程执行与 UI 相关的操作。这是一个巨大的禁忌。 【参考方案1】:

从主线程访问后,不得从后台线程对其进行修改。

这意味着您正试图在后台线程上调用onMeetingEnded()。所有 UI 工作都必须在主/UI 线程上进行。

这是你可以做的 -

func meetingEnded() 
    DispatchQueue.main.async  [weak self] in
        self?.onMeetingEnded()
    

【讨论】:

以上是关于如何用子视图卸载uiView的主要内容,如果未能解决你的问题,请参考以下文章

如何用另一个视图填充主 ViewController 上的 UIView?

如何用另一个 UIView 的矩形切割 UIView 的顶角

Vue中如何用子路由组件替换父视图

UIView 越界时隐藏子视图

UIView 子视图没有响应更改

如何用你的不同尺寸的子视图制作 UIStackView?