2013-07-15 47 views
4

我已經開始欣賞Auto Layout爲我所做的工作,但我與布倫特西蒙斯就not using Interface Builder這個話題建立了約束。 Apple提供的界面非常靈活,但非常詳細,可用於代碼生成器,而不是人爲使用。對我來說,它通過重複長度相同的前綴和很少使用的參數來模擬所有含義,而不是提供清晰的代碼,從而體現出最糟糕的Objective-C。我已經看到Florian Kugler's FLKAutoLayout隱藏約束創建在UIView類別。如何處理代碼中的NSLayoutConstraint詳細程度?

是否有其他方法可以使代碼清理器中的佈局約束更容易理解?

回答

1

我試圖保持儘可能接近蘋果的實現,承認的NSLayoutConstraint存在,所以我只是定義了一組Concise Auto Layout macros,從屬性和關係刪除前綴和包裹約束創建在構造函數函數宏(也省略,我從來沒有使用乘法器參數):

  • Constraint
  • ConstantConstraint
  • VisualConstraints
  • VisualConstraintWithMetrics

要附加多個簡單的限制,以查看,我將它們包裝在數組文本。我總是在一個符號前面加上非零常數,以強調位移。在實踐中它看起來像這樣(實例變量reffer到的意見):

[self.view addConstraints: 
@[Constraint(_verticalSeparator, CenterX, Equal, _top, CenterX, 0), 
Constraint(_verticalSeparator, CenterY, Equal, _top, CenterY, +22), 
Constraint(_verticalSeparator, Height, Equal, _localWeather, Height, 0), 
Constraint(_localWeather, CenterY, Equal, _verticalSeparator, CenterY, 0), 
Constraint(_addLocation, CenterY, Equal, _verticalSeparator, CenterY, 0), 
Constraint(_touchDown, Trailing, Equal, _verticalSeparator, Trailing, -1), 
Constraint(_touchDown, CenterY, Equal, _localWeather, CenterY, 0), 
Constraint(_touchDown, Width, Equal, _localWeather, Width, +26), 
Constraint(_touchDown, Height, Equal, _localWeather, Height, 0) 
]]; 

id f = @"[_localWeather]-space-[_verticalSeparator]-space-[_addLocation]"; 
[self.view addConstraints: 
VisualConstraintWithMetrics(f, @{@"space": @11}, 
          _localWeather, _verticalSeparator, _addLocation)]; 


[_tableCell addConstraint:ConstantConstraint(_tableCell, Height, Equal, 44)]; 

當意見組處理所有共享相同的設置,我列舉了數組文字是這樣的:

[@[_top, _middle, _bottom, _touchDown, _verticalSeparator] 
enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) { 
    view.translatesAutoresizingMaskIntoConstraints = NO; 
    [self.view addSubview:view]; 
}]; 

灌裝在superview水平經常發生的是,它被提升到了自己的宏:

[@[_top, _middle, _bottom] enumerateObjectsUsingBlock:horizontallyFillSuperview]; 

爲我的風格演變我會更新這個答案...

9

Masonry Jonas Budelmann是一款用於自動佈局的DSL,它比手動創建的線條和線條佈局約束更具可讀性。 Via iOS Dev Weekly

UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10); 

[view1 mas_makeConstraints:^(MASConstraintMaker *make) { 
    make.top.equalTo(superview.mas_top).with.offset(padding.top); 
    make.left.equalTo(superview.mas_left).with.offset(padding.left); 
    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom); 
    make.right.equalTo(superview.mas_right).with.offset(-padding.right); 
}]; 

它也有一個設置的邊緣,尺寸和中心複合限制:

// make top, left, bottom, right equal view2 
make.edges.equalTo(view2); 

// make top = superview.top + 5, left = superview.left + 10, 
//  bottom = superview.bottom - 15, right = superview.right - 20 
make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20)) 

// make width and height greater than or equal to titleLabel 
make.size.greaterThanOrEqualTo(titleLabel) 

// make width = superview.width + 100, height = superview.height - 50 
make.size.equalTo(superview).sizeOffset(CGSizeMake(100, -50)) 

// make centerX and centerY = button1 
make.center.equalTo(button1) 

// make centerX = superview.centerX - 5, centerY = superview.centerY + 10 
make.center.equalTo(superview).centerOffset(CGPointMake(-5, 10)) 
+0

+1用於命名您的來源。 – Simon

0

您也可以使用Parus lib中指定的約束。 這個lib的主要思想是不從NSLayoutConstraint本身離散,並允許你按照你的需要操作約束。

例如:

[self.view addConstraints: 
@[Constraint(_verticalSeparator, CenterX, Equal, _top, CenterX, 0), 
    Constraint(_verticalSeparator, CenterY, Equal, _top, CenterY, +22), 
    Constraint(_verticalSeparator, Height, Equal, _localWeather, Height, 0), 
    Constraint(_localWeather, CenterY, Equal, _verticalSeparator, CenterY, 0), 
    Constraint(_addLocation, CenterY, Equal, _verticalSeparator, CenterY, 0), 
    Constraint(_touchDown, Trailing, Equal, _verticalSeparator, Trailing, -1), 
    Constraint(_touchDown, CenterY, Equal, _localWeather, CenterY, 0), 
    Constraint(_touchDown, Width, Equal, _localWeather, Width, +26), 
    Constraint(_touchDown, Height, Equal, _localWeather, Height, 0) 
]]; 

id f = @"[_localWeather]-space-[_verticalSeparator]-space-[_addLocation]"; 
[self.view addConstraints: 
VisualConstraintWithMetrics(f, @{@"space": @11}, 
         _localWeather, _verticalSeparator, _addLocation)]; 

看起來像:

[self.view addConstraints PVGroup(@[ 
    PVCenterXOf(_verticalSeparator).equalTo.centerXOf(_top), 
    PVCenterYOf(_verticalSeparator).equalTo.centerYOf(_top).plus(22), 
    PVHeightOf(_verticalSeparator).equalTo.heightOf(_localWeather), 
    PVCenterYOf(_localWeather).equalTo.centerYOf(_verticalSeparator), 
    PVCenterYOf(_addLocation).equalTo.centerYOf(_verticalSeparator), 
    PVTrailingOf(_touchDown).equalTo.trailingOf(_verticalSeparator).minus(1), 
    PVCenterYOf(_touchDown).equalTo.centerYOf(_localWeather), 
    PVWidthOf(_touchDown).equalTo.widthOf(_localWeather).plus(26), 
    PVHightOf(_touchDown).equalTo.heightOf(_localWeather), 
    PVVFL("[_localWeather]-space-[_verticalSeparator]-space-[_addLocation]"), 
]).withViews(NSDictionaryOfVariableBindings(_localWeather, _verticalSeparator, _addLocation)) 
    .withMetrics(@{@"space": @11}).asArray]; 

而且Parus可以處理不正確的情況下比如

Constraint(_verticalSeparator, CenterY, Equal, _top, Width, +22) 

等。