如何从 Multipeer Connectivity Session 更改视图 UILabel、UIButtons、UIViews 等?

Posted

技术标签:

【中文标题】如何从 Multipeer Connectivity Session 更改视图 UILabel、UIButtons、UIViews 等?【英文标题】:How to change a views UILabels, UIButtons, UIViews, etc. from a Multipeer Connectivity Session? 【发布时间】:2015-01-22 19:40:07 【问题描述】:

现在已经 4 天了,我一直在尝试更改属于在多点连接会话中连接的对等点的视图或视图元素。会话已创建,我能够连接两个设备并在两者之间发送数据,但每当我尝试更改标签时,什么都没有发生。当我使用NSLog 查看label.text 是什么时,它返回null。

这是我的会话didReceiveData: 方法:

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID 
NSLog(@"did receive data, %@", peerID.displayName);
NSDictionary *dict = @
                       @"data": data,
                       @"peerID": peerID
                       ;
[[NSNotificationCenter defaultCenter] postNotificationName:@"MCDidReveiveDataNotification" object:nil userInfo:dict];

NSArray *arrayFromData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSString *gesture = [arrayFromData objectAtIndex:0];
UILabel *tapLabel = [arrayFromData objectAtIndex:1];
NSString *tapString = tapLabel.text;

[_gestureViewController receivedTap:gesture withLabelText:tapString]; 

我尝试将 UILabel 与数据以及普通的 NSString 一起发送。当我调用gestureViewController 方法时, receivedTap:gesture withLabelText:tapString 我可以 NSLog 标签文本,但是当我尝试将当前 viewController 的 tapGestureLabel 设置为 tapString 文本时,没有任何反应。

这是我的receivedTap:gesture withLabelText:tapString 方法:

- (void)receivedTap:(NSString *)gesture withLabelText:(NSString *)labelText 
NSLog(@"%@", gesture);
NSLog(@"%@", labelText);
self.tapGestureLabel.text = labelText; 

我的调度到主线程的想法:

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID 
NSDictionary *dict = @
                       @"data": data,
                       @"peerID": peerID
                       ;
[[NSNotificationCenter defaultCenter] postNotificationName:@"MCDidReceiveDataNotification" object:nil userInfo:dict];
NSArray *arrayFromData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
UIImage *image = [arrayFromData objectAtIndex:2];
[self performSelectorOnMainThread:@selector(changeImage:) withObject:image waitUntilDone:NO];

我的changeImage:选择器方法:

- (void)changeImage:(UIImage *)image 
[_gestureViewController.imageView setImage:image];

【问题讨论】:

When we are working with MCSessionState, didChangeState responds very slowly we could not find why的可能重复 【参考方案1】:

session:didReceiveData 由 Multiipeer Connectivity Framework 从专用线程调用。您正在尝试从此专用线程更新标签。这是不允许的,您应该只访问主队列中的 UI 元素。解决方案是将更新标签的代码分派到主队列。

在 receivedTap:withLabelText 中可以这样做:

- (void)receivedTap:(NSString *)gesture withLabelText:(NSString *)labelText 
    NSLog(@"%@", gesture);
    NSLog(@"%@", labelText);
    dispatch_async(dispatch_get_main_queue(), ^
        self.tapGestureLabel.text = labelText; 
    );

或者在 session:didReceiveData:fromPeer 之前处理一下

dispatch_async(dispatch_get_main_queue(), ^
    [_gestureViewController receivedTap:gesture withLabelText:tapString];
);

【讨论】:

太棒了,我将如何调度到主队列/线程? @PeterFennema 我在描述中添加了我认为正在调度到主线程的内容。 @PeterFennema 我在提交我的更新后看到了你的更新,我认为使用哪个是个人喜好问题 使用 [self performSelectorOnMainThread:@selector(changeImage:) withObject:image waitUntilDone:NO];成功了。

以上是关于如何从 Multipeer Connectivity Session 更改视图 UILabel、UIButtons、UIViews 等?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Multipeer Connectivity (Swift 3) 在会话中通过 didReceiveData() 调用 table.reloadData

从 Connecting 到 NotConnected 的 Multipeer Connectivity 会话

如何使用swift 4查看Multipeer Connectivity框架中的MCBrowserViewController

如何检测 Multipeer Connectivity 邀请的拒绝?

如何使用 Multipeer Connectivity 安全地停止发送图像

MultiPeer 框架避免使用 MCBrowserView?