将 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,所以当登录完成时,无论成功或失败,都会在按钮上返回

    我对@9​​87654339@ 的实现然后触发了我的自定义delegate,这需要在***UIViewController 上触发

【问题讨论】:

【参考方案1】:

要(反)证明我的理论,您需要发布您的自定义委托代码。您可以将其添加到您的问题中吗?

不过,我的猜测是,您混淆了 cell.googleSsoButton.delegatecell.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 的高度