如何从多点连接会话更改视图 UILabels、UIButtons、UIViews 等?

How to change a views UILabels, UIButtons, UIViews, etc. from a Multipeer Connectivity Session?

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

session:didReceiveData 由 Multipeer 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];
});