CoreText获取text的行高

步骤1:创建NSAttributedString

    NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:@"iOS程序在启动时会创建一个主线程,而在一个线程只能执行一件事情,如果在主线程执行某些耗时操作,例如加载网络图片,下载资源文件等会阻塞主线程(导致界面卡死,无法交互),所以就需要使用多线程技术来避免这类情况。iOS中有三种多线程技术 NSThread,NSOperation,GCD,这三种技术是随着IOS发展引入的,抽象层次由低到高,使用也越来越简单。"];
    CGRect viewRect = CGRectMake(0, 0, [UIScreen mainScreen].bounds.width, rectSize.height);  //CGRectGetHeight(self.bounds)
  

步骤2:创建绘制区域CGPathRef

    //创建一个用来描画文字的路径,其区域为当前视图的bounds  CGPath
    CGMutablePathRef pathRef = CGPathCreateMutable();
    CGPathAddRect(pathRef, NULL, viewRect);

步骤3:根据CTFramesetterRef和CGPathRef创建CTFrame

 CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attString);
    //创建由framesetter管理的frame,是描画文字的一个视图范围  CTFrame
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, 0), pathRef, nil);
    
    
    CFArrayRef lines = CTFrameGetLines(frameRef);
    获取有多少行
    CFIndex lineCount = CFArrayGetCount(lines);
    
   内存管理
    CFRelease(pathRef);
    CFRelease(frameRef);
    CFRelease(framesetterRef);
    
    // 自动获取行高
    CGFloat frameHeight = 0;
        frameHeight = lineCount*(styleModel.font.lineHeight+styleModel.lineSpace)+styleModel.lineSpace;
   
<think>根据用户的问题,用户想要在LVGL中获取表格控件(lv_table)的。结合提供的引用内容,特别是引用[3]中提到可以通过事件监听来自定义和样式,以及引用[2]中提到的调整可见数的函数,我们可以推断出可能与样式属性有关。 在LVGL中,表格的通常由以下因素决定: - 字体大小 - 间距(pad_top, pad_bottom) - 单元格边框宽度 因此,要获取,需要从当前应用的样式中提取这些属性值并计算。 具体步骤: 1. 获取表格控件的样式(通常是主样式或单元格样式)。 2. 从样式中获取字体、内边距(上、下)和边框宽度。 3. 计算 = 字体度 + 上内边距 + 下内边距 + 边框宽度(上下)。 注意:由于表格的通常是统一的(除非自定义了每的样式),所以我们可以通过第一来计算。 参考引用[3]中提到的`LV_EVENT_DRAW_PART_BEGIN`事件,我们可以通过监听这个事件来获取绘制描述符,其中包含信息。但是,如果仅仅是为了获取而不需要绘制,我们可以直接通过样式计算。 另外,引用[2]中提到`lv_roller_set_visible_row_count`函数通过样式计算,这提示我们同样可以通过样式计算表格的。 因此,我们可以这样实现: ```c // 假设有一个lv_table对象:lv_obj_t * table // 获取表格当前使用的样式(这里使用主样式,实际可能需要根据情况选择) const lv_style_t * style = lv_obj_get_style(table); // 或者使用单元格部分的样式?在表格中,单元格样式可能通过特定的部分设置,但通常由单元格样式决定。 // 更准确的方式是获取单元格部分的样式 const lv_style_t * cell_style = lv_obj_get_style_part(table, LV_TABLE_PART_CELL1); // 注意:LV_TABLE_PART_CELL1是单元格样式,如果表格有交替样式(如CELL1, CELL2),则可能相同。 // 获取字体属性 const lv_font_t * font = cell_style->text.font; lv_coord_t font_height = lv_font_get_line_height(font); // 获取内边距和边框 lv_coord_t pad_top = cell_style->text.line_space + cell_style->body.padding.top; // 注意:line_space是间距,在样式中可能是text.line_space lv_coord_t pad_bottom = cell_style->body.padding.bottom; lv_coord_t border_width = cell_style->body.border.width; // 计算 lv_coord_t row_height = font_height + pad_top + pad_bottom + 2 * border_width; // 上下边框 ``` 但是,请注意,在LVGL中,表格的可能还包括其他因素,比如阴影等,但通常主要考虑上述因素。 另外,引用[3]中提到在事件`LV_EVENT_DRAW_PART_BEGIN`中,通过`lv_obj_draw_part_dsc_t`结构体可以获取绘制信息,其中就包含。如果你已经在使用这个事件,那么可以直接从事件参数中获取: ```c static void event_handler(lv_event_t * e) { if(e->code == LV_EVENT_DRAW_PART_BEGIN) { lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e); // 判断是否是表格的绘制 if(dsc->part == LV_TABLE_PART_CELL1 || dsc->part == LV_TABLE_PART_CELL2 ...) { // 此时,dsc->rect 包含了该单元格的位置和大小,因此就是dsc->rect.y2 - dsc->rect.y1 // 但是注意,这个事件是针对每个单元格的,所以同一的单元格度相同,取一个即可。 lv_coord_t row_height = lv_area_get_height(&dsc->rect); } } } ``` 这种方法更直接,但需要事件触发(即表格绘制时)。如果你需要在绘制前获取,则只能通过样式计算。 总结:推荐方法是通过样式计算,因为这样不依赖于绘制事件。 注意:不同版本的LVGL可能在样式属性上有所差异,请根据实际使用的版本进调整。 最后,如果用户需要动态改变,请参考引用[3]中的方法,通过设置样式来实现。 相关问题: 1. 如何在LVGL中设置表格的? 2. LVGL表格控件如何自定义不同的样式? 3. 如何监听LVGL表格的绘制事件?</think>在 LVGL 中获取表格(`lv_table`)的方法主要有以下两种实现方式: ### 方法 1:通过样式计算(推荐) 表格由字体大小、内边距和边框共同决定: ```c lv_obj_t *table = lv_table_create(lv_scr_act()); // 获取当前单元格样式(LVGL 8.x+) const lv_style_t *style = lv_obj_get_style_part(table, LV_TABLE_PART_CELL1); // 计算公式 lv_coord_t row_height = lv_font_get_line_height(style->text.font) + // 字体度 style->body.padding.top + // 上内边距 style->body.padding.bottom + // 下内边距 (style->body.border.width * 2); // 上下边框宽度 printf("Table row height: %d px\n", row_height); ``` ### 方法 2:通过绘制事件实时获取 监听绘制事件获取精确像素值(需在渲染后生效): ```c static lv_coord_t actual_row_height = 0; void event_cb(lv_event_t *e) { if(e->code == LV_EVENT_DRAW_PART_BEGIN) { lv_obj_draw_part_dsc_t *dsc = lv_event_get_draw_part_dsc(e); if(dsc->part == LV_TABLE_PART_CELL1) { // 获取当前单元格绘制区域度 actual_row_height = dsc->rect.y2 - dsc->rect.y1 + 1; } } } // 创建表格并绑定事件 lv_obj_t *table = lv_table_create(lv_scr_act()); lv_obj_add_event_cb(table, event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL); // 刷新表格后获取值 lv_obj_invalidate(table); printf("Actual row height: %d px\n", actual_row_height); ``` ### 关键因素说明 1. **字体度**:通过 `lv_font_get_line_height()` 获取 2. **内边距**:从样式的 `body.padding.top/bottom` 获取 3. **边框宽度**:从样式的 `body.border.width` 获取 4. **间距**:通过 `style->text.line_space` 调整(影响多文本) > 提示:计算依赖当前应用的样式,修改样式后需要重新计算。如果表格启用了滚动,需考虑 `lv_table_set_scroll_propagation()` 的影响[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值