【问题标题】:All UITableCells disappear when tapping on UITableView in iOS 7在 iOS 7 中点击 UITableView 时所有 UITableCells 都会消失
【发布时间】:2014-10-22 23:54:36
【问题描述】:

我在 iOS7 中的 UITableView 出现问题。最初,数据加载得很好,我在控制台中得到输出,证明单元格正确地与数据源对话,但是只要我点击表格上的任何位置,单元格就会消失,表格就会消失空白。空 UITableView 中单元格的高度似乎符合我的自定义原型单元格(410px)的高度,但是单元格中的所有数据都消失了,空表视图的行为就像它只有一个单元格一样(就像它的默认值一样在它连接到委托之前的状态)。

我正在为这个应用程序使用故事板。

为了了解一些情况,这个应用程序类似于 iphone Instagram 应用程序,我正在使用这个应用程序来学习 iOS 7 开发。我一直在努力解决这个问题,但我找不到任何可以帮助我解决这个问题的在线资源,所以我想问问 Stack Overflow 上的所有聪明人。

我已经准备了一个图表,可以帮助你看到问题

higher resolution version here

这是我的 TableViewController 代码:

@interface PA_PhotoTableViewController ()

@property (nonatomic, copy) NSArray *photos;

@end



@implementation PA_PhotoTableViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    self.photos = [[PA_PhotoStore sharedPhotoStore] allPhotos];
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[[PA_PhotoStore sharedPhotoStore] allPhotos] count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    PA_PhotoCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PhotoCell" forIndexPath:indexPath];


    PA_Photo *photo = (self.photos)[indexPath.row];

    cell.photoTitle.text = photo.title;
    cell.photoOwnerName.text = [NSString stringWithFormat:@"%@", photo.owner];
    cell.photoLikes.text = @"99";

    // Photo Image URL
    NSURL *photoImageURL = [NSURL URLWithString:photo.image_full_url];
    [cell.photoImage sd_setImageWithURL:photoImageURL placeholderImage:[UIImage imageNamed:@"lightGraySpinningLoader.gif"]];

    // Photo Owner Image
    [cell.photoOwnerImage sd_setImageWithURL:photoImageURL placeholderImage:[UIImage imageNamed:@"lightGraySpinningLoader.gif"]];


    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // This code never gets called when I try to tap on a cell
    NSLog(@"A row was selected");
}


- (void)dealloc {
    NSLog(@"dealloc called in PA_PhotoTableViewController");
}

这是自定义单元代码 PA_PhotoCell(合并的 .h 和 .m 文件):

@interface PA_PhotoCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UIImageView *photoImage;
@property (nonatomic, weak) IBOutlet UILabel *photoTitle;
@property (nonatomic, weak) IBOutlet UILabel *photoOwnerName;
@property (nonatomic, weak) IBOutlet UIImageView *photoOwnerImage;
@property (nonatomic, weak) IBOutlet UILabel *photoLikes;
@property (nonatomic, weak) IBOutlet UILabel *photoTimestamp;
@property (nonatomic, weak) IBOutlet UILabel *photoComments;

@end



@implementation PA_PhotoCell

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    NSLog(@"in set selected");
}


-(void)setHighlighted:(BOOL)highlighted {
    NSLog(@"in set highlighted");
}

您可以看到几个NSLog() 呼叫,以帮助我查看是否有任何呼叫。

我哪里错了?最终目标是单击其中一个 TableViewCell 实例并启动 UINavigationController,我知道该怎么做,但是在弄清楚为什么我的 UITableView 不会滚动以及为什么它消失之前,我无法继续执行该步骤当我点击它时!

编辑: 经过大量测试、调试和实验,我已经能够得出结论,问题实际上根本不在于 UITableView,而在于事实上,UITableView 如何加载到其父视图中存在问题。我仍然没有找到解决问题的方法,但我离找到原因越来越近了。以下是我的发现:

首先,当点击屏幕底部的任何 UIButtons(参见图片参考)时,它会将 UIViewController 的相关实例加载到名为 placeholderView 的 UIView 中。当我在这个 UIView 之外运行有问题的 UITableView 时(其中 UITableViewController 自行运行,而不是嵌入到另一个 UIView 中),那么表格可以完美地工作,它会滚动,它会恢复点击事件等等。因此,一旦我将 UITableView 加载到 UIView 中,UITableView 就会变得无响应(它不会滚动或接收点击事件)并且任何与它交互的尝试,UITableView 都会完全空白。我的调试会话得出的结论是 NSArray *photos 永远不会重置为零,或者无论如何都不会被操纵,表格只是空白。

那么有没有人知道什么会导致 UITableView 在加载到通用 UIView 时执行此操作?加载到此通用 UIView 中的所有其他视图都是响应式的,并且按预期运行。只是这个 UITableView 给我带来了问题。

如果您查看我附在这篇文章中的图片(上图),您会发现我使用的似乎是一个 UITabBarView,但实际上它只是一个内部带有 UIButton 的通用视图。我决定制作自己的“UITabBarView 外观相似”而不是使用现成的 UITAbBarView 类的原因是因为我想为左下角的“菜单”按钮提供自定义功能(我想要一个漂亮的 UIView 滑入从左侧开始,当点击“菜单”按钮时,在屏幕右侧停止大约 60 像素,我无法弄清楚如何自定义 UITabBarView 的行为,所以我选择了这种方法。

以下是实际将 UITableViewController 加载到子视图中的代码(通过 CustomStoryboardSegway):

// PA_HomeViewCustomStoryboardSegue.m

#import "PA_HomeViewCustomStoryboardSegue.h"
#import "PA_HomeViewController.h"

@implementation PA_HomeViewCustomStoryboardSegue

// to create a custom segue, you have to override the perform method
-(void)perform {

    // get the source and destination view controllers
    PA_HomeViewController *segueSourceController = (PA_HomeViewController *)[self sourceViewController];
    UIViewController *destinationController = (UIViewController *)[self destinationViewController];

    for (UIView *view in segueSourceController.placeholderView.subviews){
        [view removeFromSuperview];
    }

    segueSourceController.currentViewController = destinationController;
    [segueSourceController.placeholderView addSubview:destinationController.view];

}

@end   

这是我的 PA_HomeViewController 的头文件(视图包含“placeholderView”,这是在用户点击视图底部的 UIButtons 后加载各种 UIViewControllers 的目标视图(类似于 TabBarView) :

@interface PA_HomeViewController : UIViewController

@property (weak, nonatomic) IBOutlet UIView *placeholderView;
@property (weak, nonatomic) UIViewController *currentViewController;

@end

我希望我只是在将 UITableView 加载到 placeholderView 的方式中遗漏了一些明显的东西,而其中的某些东西导致 UITableView 完全空白。

【问题讨论】:

  • 您是否在表格视图中注册了您的单元 PA_PhotoCell?
  • 这就是我想知道的,但如果他不这样做,他会得到一个运行时异常。
  • 几个问题。听起来好像设置了 tableview 数据源,但它的行为就像未设置委托一样。此外,它的行为就像在点击一个单元格后,NSArray 的照片会以某种方式被破坏。
  • 您的 initWithStyle 看起来不正确。它应该调用[super initWithStyle:style]
  • DataSource 和 Delegate 设置了吗?您是否尝试调用 [tableView reloadData] ?

标签: ios objective-c uitableview ios7 uistoryboard


【解决方案1】:

当您在不同的视图中显示UITableView 时,您必须始终确保“托管”UITableView 的视图控制器对其控制器具有强引用。在您的情况下,将 UITableView 添加为子视图后,UITableView 的数据源似乎已被释放。

将 currentViewController 属性从 weak 更改为 strong 应该可以解决您的问题。

【讨论】:

  • 哇。经过几天的头撞墙……我所要做的就是将引用从 weak 更改为 strong。在我听从了你的建议之后,一切都很顺利!谢谢!这意味着我必须真正研究内存管理是如何工作的,这样我才能在将来避免这样的愚蠢问题。非常感谢您的帮助!
  • 很高兴它有帮助 :) 您通常会将对象类型的所有属性标记为强,但 IBOutlets、委托和其他一些特殊情况除外。
  • 在 swift 中,您需要全局声明 viewcontroller 对象,这将导致 Strong,以防如果您在本地声明它会导致单元格不断消失。
  • 对我来说:我正在使用我的 git:github.com/davidseek/SLPagingViewSwift-Swift-3-Tinder-Twitter 并且愚蠢的单元格在单击它们后消失了。把我逼疯了。然后我遇到了数据源可能是一个问题的问题,但我不知道如何使用强引用设置控制器,因为它只是实例化......但是你的评论 - 将它设置为全局对象 - 成功了。 ..所以谢谢你,晚安;)
【解决方案2】:

您需要在 swift 中全局声明 viewcontroller 对象,这将导致 Strong,以防您在本地声明它会导致单元格不断消失。

例如

var refineViewController : RefineViewController?

然后您可以使用以下不会导致单元格消失的代码访问该控制器。

func showRefineView(isFindHomeTab isFindHomeTab : Bool){


    refineViewController =   RefineViewController(nibName: String(BaseGroupedTableVC),bundle : nil)

    refineViewController!.refineSearchDelegate = self

    refineViewController!.view.frame = CGRectMake(0, -490, self.view.frame.size.width, self.view.frame.size.height)

    UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveEaseOut, animations:
        {

            self.refineViewController!.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)
            self.refineViewController!.isFindHomeTab = isFindHomeTab

        }, completion: nil)

        self.view.addSubview(refineViewController!.view)

}

【讨论】:

    【解决方案3】:

    我遇到了完全相同的问题。问题是我使用了一个自定义数据源类(称为 tableVCDataSource),并且在 ViewController 类中错误地设置了 tableView 的数据源。我在做:

    override func viewDidLoad() {
        mainTableView.dataSource = TableVCDataSource()
    }
    

    当我应该做的时候:

    fileprivate var tableVCDataSource: TableVCDataSource?
    
    override func viewDidLoad() {
        tableVCDataSource = TableVCDataSource()
        mainTableView.dataSource = tableVCDataSource
    }
    

    这解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      • 1970-01-01
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      • 1970-01-01
      相关资源
      最近更新 更多