我希望子視圖在超級視圖的後沿(具有固定寬度)和自動'換行'當超級視圖的後沿到達了。 我正在尋找一種解決方案,使Auto Layout能夠爲我完成整個工作 - without(重新)計算子視圖的大小動態變化時的行結構(例如,以其內容爲增長/縮小的文本字段)和添加或刪除約束。AutoLayout(> iOS 6)子視圖的自動和動態換行
我已經有一個(工作)解決方案,根據子視圖的預計算(重新)計算的行結構創建約束。
所以我的問題是關於是否可以找到一個解決方案,在這樣的星座中使用約束(靈活性,優先級aso),使Auto Layout能夠在需要時自動在子視圖上執行換行(在第一次加載和運行時)。
我創建了一個示例項目UILabels
作爲'子視圖'。請玩弄這個 - 或試圖說服我,我的想法是有遠見的 - 但目前還沒有實現。
實際屏幕截圖代碼如下:
這是測試動態新行自動佈局的方法,包括:延伸NSLayoutConstraint
- (void) addConstraintsForLabels : (NSArray*) labels
superview : (UIView*) superview {
for (int i = 0; i < labels.count; i++) {
UILabel* precedingLabel = i == 0 ? nil : labels[i - 1];
UILabel* label = labels[i];
[label setTranslatesAutoresizingMaskIntoConstraints: NO];
//// set all contentHuggingPriorities to no growing and no compression
[label setContentHuggingPriority: UILayoutPriorityRequired forAxis: UILayoutConstraintAxisHorizontal];
[label setContentHuggingPriority: UILayoutPriorityRequired forAxis: UILayoutConstraintAxisVertical];
[label setContentCompressionResistancePriority: UILayoutPriorityRequired forAxis: UILayoutConstraintAxisHorizontal];
[label setContentCompressionResistancePriority: UILayoutPriorityRequired forAxis: UILayoutConstraintAxisVertical];
//// constraints affecting superview
// top to superview
NSLayoutConstraint* topToSup = [NSLayoutConstraint alignEdge: NSLayoutAttributeTop ofViews: @[label, superview] relation: i == 0 ? NSLayoutRelationEqual : NSLayoutRelationGreaterThanOrEqual
spacing: 0];
// leading to superview
NSLayoutConstraint* leadingToSup = [NSLayoutConstraint alignEdge: NSLayoutAttributeLeading
ofViews: @[label, superview]
relation: i == 0 ? NSLayoutRelationEqual : NSLayoutRelationGreaterThanOrEqual
spacing: 0];
// bottom to superview
NSLayoutConstraint* bottomToSup = [NSLayoutConstraint alignEdge: NSLayoutAttributeBottom
ofViews: @[label, superview]
relation: i == labels.count - 1 ? NSLayoutRelationEqual : NSLayoutRelationLessThanOrEqual
spacing: 0];
// trailing to superview
NSLayoutConstraint* trailingToSup = [NSLayoutConstraint alignEdge: NSLayoutAttributeTrailing
ofViews: @[label, superview]
relation: NSLayoutRelationLessThanOrEqual
spacing: 0];
//// example constraints affecting preceding label
// leading to preceding label
NSLayoutConstraint* leadingToPrec = precedingLabel == nil ? nil : [NSLayoutConstraint horizontalSpacing: 0
betweenViews: @[precedingLabel, label]
flexible: NO
inMaximum: NO];
// y position to preceding label
NSLayoutConstraint* centerYToPrec = precedingLabel == nil ? nil : [NSLayoutConstraint alignEdge: NSLayoutAttributeCenterY
ofViews: @[label, precedingLabel]
relation: NSLayoutRelationEqual
spacing: 0];
// top to preceding view
NSLayoutConstraint* topToPrec = precedingLabel == nil ? nil : [NSLayoutConstraint verticalSpacing: 0
ofViews: @[precedingLabel, label]
flexible: NO
inMaximum: NO];
//// priorities
// affecting the superview
topToSup.priority = UILayoutPriorityRequired; // is either flexible or non-flexible for the first
leadingToSup.priority = UILayoutPriorityRequired; // is either flexible or non-flexible for the first
bottomToSup.priority = UILayoutPriorityRequired; // is either flexible or non-flexible for the last
trailingToSup.priority = UILayoutPriorityRequired; // it is required, that the view does not exceed the right edge of its superview
[superview addConstraints: @[trailingToSup, topToSup, leadingToSup, bottomToSup]];
// affecting the preceding view
if (i > 0) {
leadingToPrec.priority = UILayoutPriorityDefaultHigh;
centerYToPrec.priority = UILayoutPriorityDefaultHigh;
topToPrec.priority = UILayoutPriorityDefaultHigh;
[superview addConstraints: @[leadingToPrec, centerYToPrec, topToPrec]];
}
}
}
導入的類別:
@implementation NSLayoutConstraint (ConstructorAdditions)
// align edges of two views
// if one view is the superview, put it at the second position in the array
+ (NSLayoutConstraint*) alignEdge : (NSLayoutAttribute) edge
ofViews : (NSArray*) /*UIView*/ views
relation : (NSLayoutRelation) relation
spacing : (CGFloat) spacing {
NSLayoutConstraint* constraint = nil;
if (views.count == 2) {
if (edge == NSLayoutAttributeBaseline || edge == NSLayoutAttributeTrailing || edge == NSLayoutAttributeBottom || edge == NSLayoutAttributeRight) {
spacing = -spacing;
}
constraint = [NSLayoutConstraint constraintWithItem : [views objectAtIndex: 0]
attribute : edge
relatedBy : relation
toItem : [views objectAtIndex: 1]
attribute : edge
multiplier : 1.0
constant : spacing];
}
return constraint;
}
// vertical spcacing between views
// the method assumes, that the first view in the array is above the second view
+ (NSLayoutConstraint*) verticalSpacing : (CGFloat) spacing
ofViews : (NSArray*) /*UIView*/ views
flexible : (BOOL) flexible
inMaximum: (BOOL) inMax {
NSLayoutConstraint* constraint = nil;
NSLayoutRelation relation = flexible ? (inMax ? NSLayoutRelationLessThanOrEqual : NSLayoutRelationGreaterThanOrEqual) : NSLayoutRelationEqual;
if (views.count == 2) {
constraint = [NSLayoutConstraint constraintWithItem : [views objectAtIndex: 0]
attribute : NSLayoutAttributeBottom
relatedBy : relation
toItem : [views objectAtIndex: 1]
attribute : NSLayoutAttributeTop
multiplier : 1.0
constant : -spacing];
}
return constraint;
}
// horizontal spacing between views
// the method assumes, that the first view in the array is left of the second view
+ (NSLayoutConstraint*) horizontalSpacing : (CGFloat) spacing
betweenViews : (NSArray*) /*UIView*/ views
flexible : (BOOL) flexible
inMaximum: (BOOL) inMax {
NSLayoutConstraint* constraint = nil;
NSLayoutRelation relation = flexible ? (inMax ? NSLayoutRelationLessThanOrEqual : NSLayoutRelationGreaterThanOrEqual) : NSLayoutRelationEqual;
if (views.count == 2) {
constraint = [NSLayoutConstraint constraintWithItem : [views objectAtIndex: 0]
attribute : NSLayoutAttributeTrailing
relatedBy : relation
toItem : [views objectAtIndex: 1]
attribute : NSLayoutAttributeLeading
multiplier : 1.0
constant : -spacing];
}
return constraint;
}
+ (NSArray*) equalWidthOfViews : (NSArray*) views
toView : (UIView*) view
distance : (CGFloat) distance
relation : (NSLayoutRelation) relation
multiplier : (CGFloat) multiplier {
NSMutableArray* constraints = [[NSMutableArray alloc] initWithCapacity: views.count];
for (UIView* aView in views) {
[constraints addObject: [NSLayoutConstraint constraintWithItem : aView
attribute : NSLayoutAttributeWidth
relatedBy : relation
toItem : view
attribute : NSLayoutAttributeWidth
multiplier : multiplier
constant : distance]];
}
return constraints;
}
請將您提供的代碼縮減爲包含您問題的部分。您應該自己找出調用錯誤的原因,而不是委託給社區! – 2014-08-27 18:30:14
我既沒有錯誤問題,也不知道上面的截圖結果來自哪裏。不過,爲了更清晰起見,我會稍微減少一些代碼。謝謝。 – anneblue 2014-08-28 08:14:29