我已经完全重写了代码,使其更小、更整洁,并实现了相同的结果。
更新:当加载大图时,UIImageView 的固有内容大小被调整,导致其布局失调,使其宽度是设备窗口和滚动视图的两倍。我需要想办法解决这个问题。下面的代码做了一个小改变,减小了 UIImageView 的宽度,但没有让我将其设置为窗口宽度的 100%。
[captionImageView setContentCompressionResistancePriority:1 forAxis:UILayoutConstraintAxisHorizontal];
我设置了我的视图以及其中包含的一个图片UIImageView。该图片使其包含的视图宽度比设备屏幕更宽。我有一个ViewController,通过for循环加载并添加子视图,一切似乎都正常工作。在这些子视图中,我正在尝试使用自动布局来实现以下目标:
- 添加一个UIImageView并将其宽度与父窗口相同
- 将UIImage加载到其中,并使用UIViewContentModeScaleAspectFill确保图像加载得好且比例协调。
- 在此之下加载UITextView
- 在for循环中重复此过程,以便它们全部堆叠在彼此上方。
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[captionImageView(320)]|" options:0 metrics:metrics views:views]];
那么它可以正常工作,但这不是理想的解决方案,因为我希望UIImageView与设备的宽度保持一致,而设置固定宽度是不好的做法。
如果我像下面这样指定约束:
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[captionImageView]|" options:0 metrics:metrics views:views]];
假设UIImage的大小为960像素,那么它将强制其父容器视图也具有该大小。
我将我的自定义视图内容加载到滚动视图中,因此我们有水平滚动,这不好。
请注意,我正在使用UIView类别来指定view.translatesAutoresizingMaskIntoConstraints设置为NO。
#import "UIView+Autolayout.h"
@implementation UIView (Autolayout)
+(id)autoLayoutView {
UIView *view = [self new];
view.translatesAutoresizingMaskIntoConstraints = NO;
return view;
}
@end
以下是自定义视图的代码。有什么想法可以确保我的UIImageView大小不会超出设备窗口的边界吗?
//
// FigCaptionView.m
//
//
// Created by Matthew Finucane on 18/12/2014.
// Copyright (c) 2014 The App. All rights reserved.
//
#import "FigCaptionView.h"
#import "UIView+Autolayout.h"
@interface FigCaptionView(){}
@end
@implementation FigCaptionView
-(id)initWithData:(NSDictionary *)viewData {
if((self = [FigCaptionView autoLayoutView])) {
self.figCaptionData = viewData;
}
return self;
}
-(void)layoutItems {
[self setBackgroundColor:[UIColor redColor]];
/**
* The container view for everything
*/
UIView *containerView = [UIView autoLayoutView];
/**
* Setting up the caption image
*/
UIImageView *captionImageView = [UIImageView autoLayoutView];
[captionImageView setContentMode:UIViewContentModeScaleAspectFill];
/**
* Grabbing the image (not yet the right way to do this)
*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://placekitten.com/960/240"] options:0 error:nil]];
dispatch_async(dispatch_get_main_queue(), ^{
captionImageView.image = image;
});
});
/**
* Setting up the caption image
*/
UITextView *captionTextView = [UITextView autoLayoutView];
[captionTextView setText:@"Sample paragraph text will go in here. Sample paragraph text will go in here. Sample paragraph text will go in here. Sample paragraph text will go in here. Sample paragraph text will go in here.Sample paragraph text will go in here"];
/**
* Adding the container view
*/
[self addSubview:containerView];
[containerView addSubview:captionImageView];
[containerView addSubview:captionTextView];
[captionTextView setBackgroundColor:[UIColor blueColor]];
/**
* Dictionaries for autolayout: views and metrics
*/
NSDictionary *views = NSDictionaryOfVariableBindings(containerView, captionImageView, captionTextView);
NSDictionary *metrics = @{@"imageHeight": @"160.0", @"margin": @"20.0"};
/**
* Setting up the constraints for this view
*/
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView]|" options:0 metrics:metrics views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView]|" options:0 metrics:metrics views:views]];
/**
* Container view constraints
*
* The first constraint is the one that might be causing me trouble.
*/
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[captionImageView]|" options:0 metrics:metrics views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[captionTextView]|" options:0 metrics:metrics views:views]];
[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[captionImageView(imageHeight)][captionTextView]|" options:NSLayoutFormatAlignAllLeft metrics:metrics views:views]];
for(UIView *view in self.subviews) {
if([view hasAmbiguousLayout]) {
NSLog(@"OOPS");
NSLog(@"<%@:0x%0x>", view.description, (int)self);
}
}
}
@end
code
CGRect superBounds = [[UIScreen mainScreen] bounds];NSDictionary *views = NSDictionaryOfVariableBindings(containerView, captionImageView, captionTextView); NSDictionary *metrics = @{@"imageWidth": @(superBounds.size.width), @"imageHeight": @"160.0", @"margin": @"20.0"};
- matfin