我有一组显示在 TableView 单元格中的 UILabel。当用户触摸单元格时,标签会展开以显示我在其中放置的所有文本,而不是截断的两行文本。
动画和扩展有效,但是当我再次按下标签以使其缩小 TableViewCell 时,标签正确调整大小,但标签没有。我已经通过 NSLog 调整了标签的大小,并且以编程方式我的代码可以工作,但无法正确绘制。
这是我的 cellForRowAtIndexPath 方法:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *sectionContents = [[self tableData] objectAtIndex:[indexPath section]];
NSString *contentForRow = [sectionContents objectAtIndex:[indexPath row]];
UILabel *label = nil;
int noOfLines;
UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];
label = [[UILabel alloc] initWithFrame:CGRectZero];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
label.text = contentForRow;
if ([expandedIndexPathsArray containsObject:indexPath])
{
noOfLines = 0;
CGSize size = [contentForRow sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
label.frame = CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f));
NSLog(@"height is now %f",label.frame.size.height);
} else {
noOfLines = 2;
CGSize size = [contentForRow sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
label.frame = CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MIN(size.height, 44.0f));
NSLog(@"height is now %f",label.frame.size.height);
}
NSLog(@"Number of Lines: %d",noOfLines);
label.lineBreakMode = UILineBreakModeWordWrap;
label.backgroundColor = [UIColor blueColor];
label.font = [UIFont systemFontOfSize:FONT_SIZE];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
label.numberOfLines = noOfLines;
[[cell contentView] addSubview:label];
[label release];
return cell;
}
任何人都可以告诉我这里发生了什么,因为我正在努力理解它。
提前致谢! :D
最佳答案
您发布的代码没有出现(根据您的评论)将新标签层叠在旧标签上。然而,它确实会在每次调用该方法时生成一个全新的单元格。这不是通常的设计模式。
通常的模式是回收细胞,只有在回收细胞不可用时才创建新细胞。使用这种方法,您确实需要(根据您的评论)某种方式来跟踪标签。 (执行此操作的一种方法如下面的代码片段所示。)
您还没有发布您的 tableView:heightForRowAtIndexPath: 方法。根据那里发生的情况,您可能会出现奇怪的行为,即如果行高与标签高度不匹配。当您在 tableView 上调用 reloadData (或相关方法之一)时,也不清楚。这确实需要调用,以便 iOS 可以刷新单元格行高。也许这在您的代码中没有问题 - 但绝对值得检查。
我已经测试了以下代码,它以我认为您在问题中尝试实现的方式扩展和减少了单元格。为了方便起见,这段代码只是测试行是否与给定的数字匹配,以确定它是否被展开。您将用 [expandedIndexPathsArray containsObject:indexPath] 替换我的 ([indexPath row] == _pgSpecialRow)。
我通过添加两个额外的方法将工作分开(尽管这里的代码总共更少)。这部分是为了提高可读性,部分是因为 tableView:heightForRowAtIndexPath: 方法需要执行与 tableView:cellForRowAtIndexPath: 方法相同的总和
- (UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* cellIdentifier = @"Cell";
// see if there's a cell available to recylce
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
// there's no cell to recycle, so make a new one
// add a label to it and tag the label so we can find it later
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier];
UILabel* label = [[UILabel alloc] init];
// do set up on label that doesn't vary with cell content
[label setTag: 101];
label.lineBreakMode = UILineBreakModeWordWrap;
label.backgroundColor = [UIColor blueColor];
label.font = [UIFont systemFontOfSize:FONT_SIZE];
[[cell contentView] addSubview:label];
[label release];
}
// either on a recycled cell or on the cell just created, set the contents
NSArray *sectionContents = [[self tableData] objectAtIndex:[indexPath section]];
NSString *contentForRow = [sectionContents objectAtIndex:[indexPath row]];
UILabel* label = (UILabel*)[[cell contentView] viewWithTag:101];
[self adjustLabel: label forText:contentForRow andExpanded:([indexPath row] == _pgSpecialRow)];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void) adjustLabel: (UILabel*) label forText: (NSString*) text andExpanded: (BOOL) expanded;
{
label.text = text;
CGFloat height = [self heightForLabelWithText: text expanded: expanded];
label.frame = CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), height);
label.numberOfLines = expanded ? 0: 2;
}
- (CGFloat) heightForLabelWithText: (NSString*) text expanded: (BOOL) expanded;
{
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
if (expanded)
{
return MAX([text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap].height, 44.0);
}
return MIN([text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap].height, 44.0);
}
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *sectionContents = [[self tableData] objectAtIndex:[indexPath section]];
NSString *contentForRow = [sectionContents objectAtIndex:[indexPath row]];
// return a cell height that's big enough (with a bit of extra margin)
return [self heightForLabelWithText: contentForRow expanded:([indexPath row] == _pgSpecialRow)]+ 16.0;
}
关于iphone - iOS UILabel 不重绘到新尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7135834/
我一直在做一些研究,我想我已经知道答案了,但我想知道是否有任何方法可以在不使用javascript或依赖CSS3媒体的情况下获得设备的屏幕尺寸和像素密度查询。本质上,我正在研究如何获取屏幕分辨率和像素密度,以便服务器可以决定在URI请求中为服务器提供哪个图像。到目前为止,我还没有发现任何证据表明这是可能的,但我想嘿,为什么不问问呢? 最佳答案 我不完全同意上面的正确答案。实际上,这个答案在很多情况下都是正确的……但理论上并非如此。通常向Web服务器发出的请求包含一个User-Agent字段,从理论上讲,该字段可用于识别有关设备屏幕分
给定以下ruby数组:["2XL","3XL","4XL","5XL","6XL","L","M","S","XL"]如何对其进行排序以使其符合此顺序?["S","M","L","XL","2XL","3XL","4XL","5XL","6XL"]请注意,每种尺寸并不总是存在。为了历史的缘故,这是我最初的实现。sorted_sizes=[]sorted_sizes 最佳答案 ["S","M","L","XL","2XL","3XL","4XL","5XL","6XL"]&["2XL","3XL","4XL","5XL","6XL
我正在构建一个与RubyonRails后端对话的iPhone应用程序。RubyonRails应用程序还将为Web用户提供服务。restful_authentication插件是提供快速和可定制的用户身份验证的绝佳方式。但是,我希望iPhone应用程序的用户在新列中存储一个由手机的唯一标识符([[UIDevicedevice]uniqueIdentifier])自动创建的帐户。稍后,当用户准备好创建用户名/密码时,帐户将更新为包含用户名和密码,iPhone唯一标识符保持不变。用户在设置用户名/密码之前不能访问该网站。然而,他们可以使用iPhone应用程序,因为该应用程序可以使用它的标识符
当我输入这个时:puts'repeat'*3我得到:>>repeatrepeatrepeat但是如果我这样做是行不通的:puts3*'repeat'为什么? 最佳答案 在Ruby中,当你调用a*b时,您实际上是在调用一个名为*的方法在a.试试这个,例如:a=5=>5b=6=>6a.*(b)=>30c="hello"=>"hello"c.*(a)=>"hellohellohellohellohello"因此*工作正常,因为*String上的方法了解如何处理整数。它通过将自身的多个副本连接在一起来做出响应。但是当你做3*"repeat"
我有一个使用deviseonrails3的应用程序。我想启用http身份验证,以便我可以从iPhone应用程序向我的网络应用程序进行身份验证。如何从我的iPhone应用程序进行身份验证以进行设计?这安全吗?还是我应该进行不同的身份验证? 最佳答案 从设计的角度来看,您有3个选择:1)使用基本的http身份验证:您的iPhone应用程序有一个secretkey-这是在您的iPhone应用程序代码中烘焙的-用于对网络应用程序的每个请求进行身份验证。Google搜索:“设计基本的http身份验证”2)您可以通过在您的iPhone应用程序中
是否有任何Rubygem/库可以帮助您从旧的数据库结构迁移到新的结构?ActiveRecord迁移在跟踪新数据库结构方面做得很好,但我想知道是否有什么可以帮助您将整个遗留数据库迁移到新结构:transfer_from(:source_table=>'person',:destination_table=>'dudes_and_dudets')dofrom:name,:to=>:full_namefrom:dob,:to=>:agedo|dob|#thiswould,forexample,loadtheresult(Date.today-dob)/60/60/24/365#ofthebl
有没有一种方法可以为多个角色声明attr_accessible而无需大量重复?如果我有多个用户角色,并且允许每个角色编辑不同的属性子集,那么我的attr_accessible声明如下所示:attr_accessible:first_name,:last_name,:active,:as=>:adminattr_accessible:first_name,:last_name,:as=>:managerattr_accessible:first_name,:last_name,:as=>:guest我也愿意A)定义一组可以共享的可访问属性不同的角色或B)定义一组可以访问相同角色的角色属性
使用带有以下gem的Rails3.2.8的应用程序gem'friendly_id','~>4.0'gem'route_translator'在/config/initializers/i18n.rbTLD_LOCALES={"com"=>:en,"jobs"=>:en,"net"=>:en,"in"=>:en,"de"=>:de,"ch"=>:de,"at"=>:de,"br"=>:pt,"ar"=>:es,"cl"=>:es,"mx"=>:es}在/app/controllers/application_controller.rb中,使用前置过滤器为每个请求设置语言环境:before
这个问题在这里已经有了答案:关闭13年前。PossibleDuplicates:HowcanIdevelopforiPhoneusingaWindowsdevelopmentmachine?我想为我妻子的手机构建一个iPhone应用程序,但我对购买Mac作为一次性工作的开发平台不感兴趣。应用程序:应该在iPhone上独立运行(即没有网络连接)完全可以接受使用iPhoneJavascript库之一创建的GUI会做一些数据库IO来读取和更新数据没有商业值(value),永远不会被任何人使用这是我的想法:越狱iPhone在iPhone上安装Ruby+Sinatra使用Sinatra编写应用程
我正在试验iPhoneSDK并在Nic博士的rbiPhoneTest项目中做一些TDD。我想知道有多少人(如果有的话)成功地使用了这个或任何其他iPhone/Cocoa测试框架?更重要的是,我想知道如何最好地断言专有的二进制请求/响应协议(protocol)。这个想法是通过网络发送二进制请求并接收二进制响应。请求和响应是使用byteand'ing和or'ing创建的。我正在使用黄金副本模式来测试我的请求。这是我到目前为止所拥有的。不要笑,因为我是ObjectiveC和Ruby的新手:requireFile.dirname(__FILE__)+'/test_helper'require'