iOS: 使用滚动功能显示图像和长文本的正确方法
iOS: The proper way to display Images and long texts with scroll functionality
我正在为一个新闻网站开发一个应用程序,我正在使用 UITableView
显示新闻文章,其中每个单元格都是一个文章标题,当用户点击一个单元格(即一篇文章)时,另一个视图打开(使用 segue),现在在这个视图中我想放置以下内容:
- 文章的图片在顶部。
- 图片下方的文章日期。
- 日期下的文章描述。 (可能会很长)
- 用户滚动整个视图的能力。 (不仅是描述)
注意:我尝试了很多方法,我似乎不知道实现这个结构的正确方法。
现代解决方案实际上相对简单:将整个事物组合成属性字符串并将其放入 UITextView
。文本视图会自动处理描述可能很长、所有内容应该一起滚动等情况
例如
NSAttributedString *imageString = [NSAttributedString attributedStringWithAttachment:
[[NSTextAttachment new] setImage:[UIImage imageNamed:@"whatever.png"]]];
... 并使用自然方式来组合属性字符串以及在其他文本位上设置字体和颜色等内容。然后 textView.attributedString = compoundString;
.
详细示例:
- (void)setStory:(Story *)story
{
NSAttributedString *image = [story imageString];
NSAttributedString *date = [story dateString];
NSAttributedString *body = [story bodyString];
NSMutableAttributedString *wholeStory = [NSMutableAttributedString new];
// TODO: can you be sure image, date and body are all non-nil?
NSArray *allComponents = @[image, date, body];
for(NSAttributedString *component in allComponents)
{
[wholeStory appendAttributedString:component];
if(component != [allComponents lastObject])
[[wholeStory mutableString] appendString:@"\n\n"];
}
self.textView.attributedString = wholeStory;
}
... elsewhere, in the Story object ...
- (UIImage *)image
{
// ...something...
}
- (NSString *)dateText
{
// ...something, probably using NSDateFormatter unless it's returned
// from a server or wherever already formatted...
}
- (NSString *)bodyText
{
// ... something ...
}
- (NSAttributedString *)imageString
{
return [NSAttributedString attributedStringWithAttachment:
[[NSTextAttachment new] setImage:[self image]]];
}
- (NSAttributedString *)dateString
{
return [[NSAttributedString alloc]
initWithString:[self dateText]
attributes:
@{
NSFontAttributeName: [UIFont preferredFontForTextStyle: UIFontTextStyleSubheadline],
... etc ...
}];
}
- (NSAttributedString *)bodyString
{
return [[NSAttributedString alloc]
initWithString:[self bodyText]
attributes:
@{
NSFontAttributeName: [UIFont preferredFontForTextStyle: UIFontTextStyleBody],
... etc ...
}];
}
查看 NSAttributedString UIKit Additions 文档,了解除 NSFontAttributeName
之外您可以设置的各种属性的列表。请注意,我已经采用 iOS 7+ 方式按目的请求字体,而不是特定大小或字体。这意味着调高默认字体大小的用户将在您的应用中获得更大的文本。
另一种方法是将每篇文章显示为 UIWebView
中的 HTML 字符串。
NSURL *url = [NSURL URLWithString:self.articleController.url];
NSString *html = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL];
[self.articleView.webView loadHTMLString:html baseURL:baseURL];
我创建了一个 pod 以编程方式添加约束。 scrollViews
有一个特殊类别,因为它们与自动布局一起使用非常复杂。
这里是 link 到 project
您可以查看一个示例应用程序,但您需要做的事情是
- 初始化您的视图(图像、日期标签和描述标签)。
- 添加
scrollView
- 添加
scrollView
的子视图
UIScrollView *scrollView = [[UIScrollView alloc] init];
[self.view addSubview:scrollView];
[scrollView addConstraintsToFillHorizontal];
[scrollView addConstraintsToFillVertical];
[scrollView addConstraintsToAlignVerticalAllViews:@[image, dateLabel, descriptionLabel]];
这应该很容易实现,但如果您需要更多帮助,请告诉我,我可以为您提供更多示例代码。
祝你项目顺利!
我正在为一个新闻网站开发一个应用程序,我正在使用 UITableView
显示新闻文章,其中每个单元格都是一个文章标题,当用户点击一个单元格(即一篇文章)时,另一个视图打开(使用 segue),现在在这个视图中我想放置以下内容:
- 文章的图片在顶部。
- 图片下方的文章日期。
- 日期下的文章描述。 (可能会很长)
- 用户滚动整个视图的能力。 (不仅是描述)
注意:我尝试了很多方法,我似乎不知道实现这个结构的正确方法。
现代解决方案实际上相对简单:将整个事物组合成属性字符串并将其放入 UITextView
。文本视图会自动处理描述可能很长、所有内容应该一起滚动等情况
例如
NSAttributedString *imageString = [NSAttributedString attributedStringWithAttachment:
[[NSTextAttachment new] setImage:[UIImage imageNamed:@"whatever.png"]]];
... 并使用自然方式来组合属性字符串以及在其他文本位上设置字体和颜色等内容。然后 textView.attributedString = compoundString;
.
详细示例:
- (void)setStory:(Story *)story
{
NSAttributedString *image = [story imageString];
NSAttributedString *date = [story dateString];
NSAttributedString *body = [story bodyString];
NSMutableAttributedString *wholeStory = [NSMutableAttributedString new];
// TODO: can you be sure image, date and body are all non-nil?
NSArray *allComponents = @[image, date, body];
for(NSAttributedString *component in allComponents)
{
[wholeStory appendAttributedString:component];
if(component != [allComponents lastObject])
[[wholeStory mutableString] appendString:@"\n\n"];
}
self.textView.attributedString = wholeStory;
}
... elsewhere, in the Story object ...
- (UIImage *)image
{
// ...something...
}
- (NSString *)dateText
{
// ...something, probably using NSDateFormatter unless it's returned
// from a server or wherever already formatted...
}
- (NSString *)bodyText
{
// ... something ...
}
- (NSAttributedString *)imageString
{
return [NSAttributedString attributedStringWithAttachment:
[[NSTextAttachment new] setImage:[self image]]];
}
- (NSAttributedString *)dateString
{
return [[NSAttributedString alloc]
initWithString:[self dateText]
attributes:
@{
NSFontAttributeName: [UIFont preferredFontForTextStyle: UIFontTextStyleSubheadline],
... etc ...
}];
}
- (NSAttributedString *)bodyString
{
return [[NSAttributedString alloc]
initWithString:[self bodyText]
attributes:
@{
NSFontAttributeName: [UIFont preferredFontForTextStyle: UIFontTextStyleBody],
... etc ...
}];
}
查看 NSAttributedString UIKit Additions 文档,了解除 NSFontAttributeName
之外您可以设置的各种属性的列表。请注意,我已经采用 iOS 7+ 方式按目的请求字体,而不是特定大小或字体。这意味着调高默认字体大小的用户将在您的应用中获得更大的文本。
另一种方法是将每篇文章显示为 UIWebView
中的 HTML 字符串。
NSURL *url = [NSURL URLWithString:self.articleController.url];
NSString *html = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL];
[self.articleView.webView loadHTMLString:html baseURL:baseURL];
我创建了一个 pod 以编程方式添加约束。 scrollViews
有一个特殊类别,因为它们与自动布局一起使用非常复杂。
这里是 link 到 project
您可以查看一个示例应用程序,但您需要做的事情是
- 初始化您的视图(图像、日期标签和描述标签)。
- 添加
scrollView
- 添加
scrollView
的子视图
UIScrollView *scrollView = [[UIScrollView alloc] init];
[self.view addSubview:scrollView];
[scrollView addConstraintsToFillHorizontal];
[scrollView addConstraintsToFillVertical];
[scrollView addConstraintsToAlignVerticalAllViews:@[image, dateLabel, descriptionLabel]];
这应该很容易实现,但如果您需要更多帮助,请告诉我,我可以为您提供更多示例代码。
祝你项目顺利!