如何取到uitableview的自定义的sectionheader

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何取到uitableview的自定义的sectionheader相关的知识,希望对你有一定的参考价值。

参考技术A - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
UIView *v_headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 23)];//创建一个视图(v_headerView)
UIImageView *v_headerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 23)];//创建一个UIimageView(v_headerImageView)
v_headerImageView.image = [UIImage imageNamed:@"ip_top bar.png"];//给v_headerImageView设置图片
[v_headerView addSubview:v_headerImageView];//将v_headerImageView添加到创建的视图(v_headerView)中
[v_headerImageView release];//释放v_headerImageView所占用的资源
UILabel *v_headerLab = [[UILabel alloc] initWithFrame:CGRectMake(10, 1, 100, 19)];//创建一个UILable(v_headerLab)用来显示标题
v_headerLab.backgroundColor = [UIColor clearColor];//设置v_headerLab的背景颜色
v_headerLab.textColor = [UIColor grayColor];//设置v_headerLab的字体颜色
v_headerLab.font = [UIFont fontWithName:@"Arial" size:13];//设置v_headerLab的字体样式和大小
v_headerLab.shadowColor = [UIColor whiteColor];//设置v_headerLab的字体的投影
[v_headerLab setShadowOffset:CGSizeMake(0, 1)];//设置v_headerLab的字体投影的位置
//设置每组的的标题
if (section == 0)
v_headerLab.text = @"导航";

if (section == 1)
v_headerLab.text = @"专场";

[v_headerView addSubview:v_headerLab];//将标题v_headerLab添加到创建的视图(v_headerView)中
[v_headerLab release];//释放v_headerLab所占用的资源
return v_headerView;//将视图(v_headerView)返回
参考技术B 把 UITableView 的 style 属性设置为 Plain ,这个tableview的section header在滚动时会默认悬停在界面顶端。

  如果想取消悬停效果,可以采用如下2种方法

  1. 修改 UITableView 的 style 属性设置为 Grouped. 这时所有的section header都会随着scrollview滚动了。不过 grouped 和 plain 的样式有轻微区别,切换样式后也许需要重新调整UI

  2. 如果需要使用 Grouped 这种样式, 也可以通过重载 scrollView 的 delegate 来达到目的:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
CGFloat sectionHeaderHeight = 40;
if (scrollView.contentOffset.y <= sectionHeaderHeight && scrollView.contentOffset.y > =0)
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
else if (scrollView.contentOffset.y >= sectionHeaderHeight)
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);

使用大型数据库时,如何避免 UITableView 中的自定义单元格加载时间过长

【中文标题】使用大型数据库时,如何避免 UITableView 中的自定义单元格加载时间过长【英文标题】:How do I avoid long loading time with custom cell in a UITableView when using a big database 【发布时间】:2015-10-06 19:14:18 【问题描述】:

在我正在开发的应用程序中,我必须从一个相当大的数据库中获取和使用数据(文本和图像),并且当 加载 tableview 时,应用程序会冻结 2-5 秒。这可能会破坏 UX,因为 UI 感觉对操作反应不快。

我认为问题是存在许多图像(不是很重,50x50px),每个自定义 cel 都有一个,大约有1000+ 行。 我需要知道最好的方法避免这个加载时间长,或者如何隐藏它。

用户点击一个按钮打开tableview,该按钮执行一个segue,然后我在viewDidLoad() 中获取数据。正如我所知道的,viewDidLoad() 方法可以阻止交互直到完成。在 viewDidLoad() 内部,我调用了一个名为 fetchCard() 的函数。它将Card 对象放入一个数组中,该对象包含我在单元格中使用的属性(名称、缩略图)。

func fetchCard() 

    cards = []

    let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "Card")
    let sorter: NSSortDescriptor = NSSortDescriptor(key: sorterParameter , ascending: true)
    fetchRequest.predicate = definitivePredicate
    fetchRequest.sortDescriptors = [sorter]
    fetchRequest.returnsObjectsAsFaults = true

    do 
        let results = try moc.executeFetchRequest(fetchRequest)
        cards = results as! [Card]
     catch 
        print("Fetch failed: \(error)")
    

有没有办法加载,例如,只加载可见行,这行得通吗/这样做是个好习惯吗?有更好的方法吗?

P.S.:为了避免基于个人喜好的讨论,“更好”是指加载速度方面性能最高的方式。

编辑:添加代码示例。

【问题讨论】:

您是否使用 CoreData 进行本地存储?你能提供一些如何获取数据的示例代码吗? google 异步编码 @haluzak 是的,我正在使用核心数据,我将编辑我的问题。 你给表添加索引了吗?什么是大,1K,10K,100k?是所有图像都不同还是许多相同? 我获取了大约 1100 个对象。每个单元格的图像都是唯一的。 【参考方案1】:

问题是您在 viewDidLoad() 方法中加载了许多数据,并且您没有在后台线程上异步加载它们。当您在 viewDidLoad() 中调用 fetchCard() 时,您会阻止加载整个屏幕,直到从 DB 加载完成。

要在后台线程上加载数据,您必须这样做:

let queue: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
    dispatch_async(queue,  () -> Void in
        let context: NSManagedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType)
        context.parentContext = moc

        let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "Card")
        let sorter: NSSortDescriptor = NSSortDescriptor(key: sorterParameter , ascending: true)
        fetchRequest.predicate = definitivePredicate
        fetchRequest.sortDescriptors = [sorter]
        fetchRequest.returnsObjectsAsFaults = true

        do 
            let results = try context.executeFetchRequest(fetchRequest)
            cards = results as! [Card]
         catch 
            print("Fetch failed: \(error)")
        

        dispatch_async(dispatch_get_main_queue(),  () -> Void in
            tableView.reloadData()
        )
    )

此外,如果从 CoreData 加载变慢,您将不得不找出原因。为您排序/过滤的对象中的变量添加索引可能会有所帮助。在sortDescriptors中添加1个描述符,尝试索引描述符中使用的sorterParameter

如果您将图像存储在 CoreData 数据库中,最好也异步加载它们以保持 tableview 的滚动流畅。您可以使用与以前类似的代码,只需将图像加载移动到 GCD 块内并将图像设置为主线程中的图像视图('dispatch_async(dispatch_get_main_queue()...')。

【讨论】:

我试过你的代码,但是从 Core Data 加载数据仍然需要太多时间,因为我看到 tableview 是空的,过了一会儿它崩溃了。我会寻找索引和数据库:你能给我指一个关于索引的参考吗? 我也会让图片异步加载 @Qubex_ 考虑 OP 的声明:“从核心数据加载数据需要太多时间”。这真的是一个异步问题吗?并不是不应该使用异步,只是它不是当前的性能问题。 @zaph 正如你所建议的,我必须使用索引。我不知道他们,我现在正在阅读您链接的另一个答案。 @zaph 正如我所提到的,为适当的变量添加索引以加快数据库中的整个搜索速度肯定会有所帮助,我会尝试在他提供的聊天中帮助 Qubex【参考方案2】:

根据 OP 所述,问题解决方案是在疮正在使用的属性(列)上创建索引。

有关更多信息,请参阅此SO Question。然后跟进 Core Data 文档或一本好的 Core Data 书籍。

注意事项: 1. 如果表行数大约为 1000,因为 OP 暗示使用索引核心数据的访问时间应该几乎是瞬时的。

    重新生成 50 x 50 像素的图像的时间也应该是微不足道的。

    在性能问题上,重要的是要衡量性能问题在哪里,否则时间和精力会花在错误的领域上。

【讨论】:

【参考方案3】:

UITableView 已经只加载cellForRowAtIndexPath 中的可见单元格。假设您正在重用单元格,您的问题很可能在于加载数据,而不是显示数据。

看看苹果的异步加载示例项目:LazyTableImages

调整大图像的大小以适应较小的表格视图单元格大小的图像确实需要一些处理能力和相当数量的 IO。如果可能,您应该为表格视图使用较小的缩略图,而不是大图像。不过,在较新的设备上可能需要较大尺寸的图像才能注意到这一点。

【讨论】:

感谢您的链接,我将尝试实现该链接 @Qubex_ Core Data 访问应该很快,首先你需要找出什么是慢的:成像的 Core Data。您需要衡量并了解时间。 @Marcus 图片是 50 x 50,所以不是很大。

以上是关于如何取到uitableview的自定义的sectionheader的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Storyboard 中的自定义 UITableViewCell 中配置 UITableView?

如何让 UITableView 继承 UIViewController 的自定义子类?

如何在带有标题视图和 UITableview 的自定义视图中正确设置 UISearchbar 的动画?

如何更新动态生成的故事板中的自定义特定 UITableview 单元格?

Swift:如何在动态 UITableView 的自定义单元格中获取滑块的值?

如何将不同的数据发送到同一个 UITableView 中的自定义单元格?