将 UIViewController 设置为 UITableViewCell 中自定义 UIView 的委托
Posted
技术标签:
【中文标题】将 UIViewController 设置为 UITableViewCell 中自定义 UIView 的委托【英文标题】:Setting UIViewController as delegate of custom UIView within UITableViewCell 【发布时间】:2015-11-17 20:30:09 【问题描述】:所以标题几乎解释了我的问题。
我有一个UIViewController
,其中包含一个UITableView
。在所有UITableViewCells
中都有一个自定义UIButton
,但在其中一个 中,我想将delegate
设置为***UIViewController
。即点击这个按钮,触发UIViewController
上发生的事情
如果我在所有按钮上设置delegate
,这可以正常工作 - 但我不想在所有按钮上设置它。如果我尝试在tableView:cellForRowAtIndexPath:
中挑出我想要的单元格,delegate
总是以nil
结束。如果我单步执行,则在加载 tableView
时已正确设置委托,但是当我点击按钮并单步执行正在发生的事情时,委托为 nil。
包括下面我的一些tableView
代码。留下一些位以使其更快地阅读。有没有可能我被一些重复使用的东西抓住了,或者?
//视图控制器
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
cell = [self configureButtonCell:cell forIndexPath:indexPath];
return cell;
- (SLPButtonCell *)configureButtonCell:(SLPButtonCell *)cell forIndexPath:(NSIndexPath *)indexPath
NSDictionary *button = [self.buttons objectAtIndex:indexPath.row];
cell.delegate = self;
cell.indexPath = indexPath;
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (button is type 1)
//do whatever
else if (button is type2)
[GIDSignIn sharedInstance].uiDelegate = self;
cell.googleSsoButton.delegate = self;
else
//do whatever
return cell;
- (void)signInWasSuccessful
//success code happens here
- (void)signInWasUnsuccessful:(NSError *)error
//non success happens here
// Google SSO Button.h
@protocol GoogleSSOButtonDelegate <NSObject>
- (void)signInWasSuccessful;
- (void)signInWasUnsuccessful:(NSError *)error;
@end
@interface GoogleSSOButton : UIButton
@property (nonatomic, weak) id<GoogleSSOButtonDelegate> delegate;
@end
//谷歌单点登录按钮.m
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error
if (custom stuff works)
if ([_self.delegate respondsToSelector:@selector(signInWasSuccessful)])
[_self.delegate signInWasSuccessful];
else
if ([_self.delegate respondsToSelector:@selector(signInWasUnsuccessful:)])
[_self.delegate signInWasUnsuccessful:error];
给出完整的事件序列:
用户按下登录按钮 - 调用登录并触发[GIDSignIn sharedInstance].uiDelegate
。
按钮也是GIDSignInDelegate
,所以当登录完成时,无论成功或失败,都会在按钮上返回
delegate
,这需要在***UIViewController
上触发
【问题讨论】:
【参考方案1】:要(反)证明我的理论,您需要发布您的自定义委托代码。您可以将其添加到您的问题中吗?
不过,我的猜测是,您混淆了 cell.googleSsoButton.delegate
和 cell.delegate
:
- (SLPButtonCell *)configureButtonCell:(SLPButtonCell *)cell forIndexPath:(NSIndexPath *)indexPath
// here you set delegate for every cell:
cell.delegate = self;
// here you do your conditional
else if (button is type2)
[GIDSignIn sharedInstance].uiDelegate = self;
cell.googleSsoButton.delegate = self;
另外值得注意的是,[GIDSignIn sharedInstance].uiDelegate
是一个共享实例/单例 - 你不能有条件地设置它,因为只要你的 else 语句到达一次,它总是会设置为self
。建议将其移至控制器的 viewDidLoad
并移出您的表视图委托。
【讨论】:
我已将自定义委托代码添加到我的问题中。关于 uiDelegate,如果分支不能保证每次都被命中(ViewController 在几个不同的地方被重用,由 API 配置),所以不要在 viewDidLoad 中不必要地设置它 嗯,事实是,它是一个共享实例。这意味着每次您设置它时,它都会影响它使用的所有地方。我认为您应该重新考虑有关如何实施的逻辑。 那么你的代表写在哪里?在您的 SLPButtonCell 类中?或者 googleSsoButton 属于什么类? 我刚刚添加了有关代表的更多详细信息!以上是关于将 UIViewController 设置为 UITableViewCell 中自定义 UIView 的委托的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UI 元素保留在 UIViewController 及其呈现的 ViewController 之上?
UIViewControllers 中的 UIViewController
将 UIViewController 设置为 UITableViewCell 中自定义 UIView 的委托
将 Constraint 设置为与 UiViewController 相关的 UITableViewCell
左侧 UIViewController 的 ViewDeck 大小
Swift:使用 prepareForSegue 将 UIView 容器的高度设置为嵌入式 UITableView 的高度