[英]UITableView inside UIScrollView – Table Cell is not selectable
[英]How to use UITableView inside UIScrollView and receive a cell click?
我有DiscountListTableViewController
,它在我的应用程序中显示为一个单独的屏幕。 但是还有另一个屏幕( PlaceDetailsViewController
),我需要在底部显示相关的折扣。
目前, PlaceDetailsViewController.view
有UIScrollView
作为容器,我正在将DiscountListTableViewController.tableView
添加到PlaceDetailsViewController
viewDidLoad
中的这个UIScrollView.content
容器。 这有效并且表格视图显示正确,但是无法接收单元格点击。
我知道UITableView
继承自UIScrollView
并且以某种方式不建议(但不限制)。 然而,从松耦合的角度来看,每个组件都应该以一种可以在其他地方独立使用的方式设计,在我的例子中它是DiscountListTableViewController
。
PlaceDetailsViewController
组件只需PlaceDetailsViewController
DiscountListTableViewController
,所以没有逻辑上的理由不能直接使用它。 有什么建议?
回答:不要这样做。
UITableview
继承自 ----> UIScrollView : UIView : UIResponder : NSObject
苹果 说:
重要提示:您不应在 UIScrollView 对象中嵌入 UIWebView 或 UITableView 对象。 如果这样做,可能会导致意外行为,因为两个对象的触摸事件可能会混淆并错误处理。
不建议? 读完后感觉有点像“不要做”。不可预测性对于应用程序来说从来都不是一个好行为
重要提示:您不应在 UIScrollView 对象中嵌入 UIWebView 或 UITableView 对象。 如果这样做,可能会导致意外行为,因为两个对象的触摸事件可能会混淆并错误处理。
将分享如何解决。 是否继承了 UIScrollView 并在 PlaceDetailsViewController 中用作容器视图:
@interface PlaceDetailsContainerUIScrollView : UIScrollView
@end
@implementation PlaceDetailsContainerUIScrollView
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *result = [super hitTest:point withEvent:event];
if ([result isKindOfClass:[UIView class]] && (result.tag == kDiscountListTableViewCellTag)
{
UITableView *tableView = (UITableView *) [[result.superview superview] superview];
return tableView;
}
return result;
}
@end
另外,不要忘记设置 PlaceDetailsContainerUIScrollView.delaysContentTouches = YES 和 PlaceDetailsContainerUIScrollView.canCancelContentTouches = NO。
此外,需要在 DiscountListTableViewController 方法中进行小修复:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DiscountDetailsViewController *discountDetailsVC = [[DiscountDetailsViewController alloc] init];
//[self.navigationController pushViewController:discountDetailsVC animated:YES];
// self.navigationController is nill because it's not pushed on nav stack, so will grab the current one:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.navigationController pushViewController:discountDetailsVC animated:YES];
}
2020 年的更新,swift 5.X 允许您的tableview
在scrollview
!
创建 UITableView 的子类:
import UIKit final class ContentSizedTableView: UITableView { override var contentSize:CGSize { didSet { invalidateIntrinsicContentSize() } } override var intrinsicContentSize:CGSize { layoutIfNeeded() return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height) } }
将 UITableView 添加到您的布局并在所有方面设置约束。 将它的类设置为 ContentSizedTableView。
您应该会看到一些错误,因为 Storyboard 没有考虑我们的子类的intrinsicContentSize
。 在运行时,它将使用我们的 ContentSizedTableView 类中的覆盖
也许这已经晚了,但我设法通过以下方式做到了这一点:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.