问题描述
我正在开发一个 IOS 应用程序.我使用 Facebook AsyncDisplayKit 库.我想在 ASNodeCell 中添加一个按钮 我得到变量‘节点’在被块捕获时未初始化.如何在 ASNodeCell 中添加 UIButton 或 UIWebView 控件.请帮助我
I am developing an IOS application. I use Facebook AsyncDisplayKit library. I want to a button in ASNodeCell Bu I got "Variable 'node' is uninitialized when captured by block. How can I add UIButton or UIWebView control in ASNodeCell. Please help me
dispatch_queue_t _backgroundContentFetchingQueue;
_backgroundContentFetchingQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(_backgroundContentFetchingQueue, ^{
ASDisplayNode *node = [[ASDisplayNode alloc] initWithViewBlock:^UIView *{
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button sizeToFit];
node.frame = button.frame;
return button;
}];
// Use `node` as you normally would...
node.backgroundColor = [UIColor redColor];
[self.view addSubview:node.view];
});
推荐答案
请注意,在您的情况下不需要使用 UIButton,您可以使用 ASTextNode 作为按钮,因为它继承自 ASControlNode(ASImageNode 也是如此).这在指南第一页的底部有描述:http://asyncdisplaykit.org/guide/.这也将允许您在后台线程而不是主线程上进行文本大小调整(您在示例中提供的块在主队列上执行).
Note that in your case there's no need to use UIButton, you can use ASTextNode as a button since it inherits from ASControlNode (same goes for ASImageNode). This is described at the bottom of the first page of the guide: http://asyncdisplaykit.org/guide/. That will also allow you to do the text sizing on the background thread instead of the main thread (the block you provide in your example is executed on the main queue).
为了完整起见,我还将评论您提供的代码.
For completeness I'll also comment on the code you provided.
您在创建块时尝试在块中设置节点的框架,因此您在初始化期间尝试在其上设置框架.这会导致你的问题.我认为您在使用 initWithViewBlock 时实际上不需要在节点上设置框架:因为在内部 ASDisplayNode 使用该块直接创建其 _view 属性,该属性最终添加到视图层次结构中.
You're trying to set the frame of the node in the block when you're creating it, so you're trying to set the frame on it during its initialization. That causes your problem. I don't think you actually need to set the frame on the node when you're using initWithViewBlock: because internally ASDisplayNode uses the block to directly create its _view property which is added to the view hierarchy in the end.
我还注意到您正在从后台队列调用 addSubview:,您应该始终在调用该方法之前将其分派回主队列.为方便起见,AsyncDisplayKit 还向 UIView 添加了 addSubNode:.
I also noticed you're calling addSubview: from the background queue, you should always dispatch back to the main queue before you call that method. AsyncDisplayKit also adds addSubNode: to UIView for convenience.
我已更改您的代码以反映更改,但我建议您在此处使用 ASTextNode.
I've changed you're code to reflect the changes though I recommend you use ASTextNode here.
dispatch_queue_t _backgroundContentFetchingQueue;
_backgroundContentFetchingQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(_backgroundContentFetchingQueue, ^{
ASDisplayNode *node = [[ASDisplayNode alloc] initWithViewBlock:^UIView *{
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button sizeToFit];
//node.frame = button.frame; <-- this caused the problem
return button;
}];
// Use `node` as you normally would...
node.backgroundColor = [UIColor redColor];
// dispatch to main queue to add to view
dispatch_async(dispatch_get_main_queue(),
[self.view addSubview:node.view];
// or use [self.view addSubnode:node];
);
});
这篇关于使用 AsyncDisplayKit 添加自定义按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!