序文
iOSでのレイアウトにMasonryを使用することは日常業務ですが、Webページのフローティングレイアウトに似ている場合、具体的な図は次のようになります。
要素の1つを削除すると、残りの要素が特定の方向に移動します。Web側では、このレイアウト方法はフローティングレイアウトと呼ばれます。
また、以下のような状況があります。これもフローティングですが、反対側では制約関係が維持されています。これもiOSでは比較的一般的な制約状況です。
iOSでMasonryを使用して上記のプロセスを実装することは、実際には非常に面倒です。Masonryに基づいている場合、この状況に基づいて、一般に2つの記述方法があります。1つは状態を網羅する方法で、もう1つは一時的なビュー変数の記録です。方法。
州の徹底的な法律:
状態を網羅する方法は、すべてのビューの組み合わせを一覧表示し、対応する制約レイアウトを追加することです。特定の例については、次のコードを参照してください。
- (void)loseConstraintsAction {
if (!_A.hidden && !_B.hidden && !_C.hidden) {
[_A mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(20.0f);
}];
[_B mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.A.mas_right).offset(8.0f);
}];
[_C mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.B.mas_right).offset(8.0f);
}];
}
if (!_A.hidden && _B.hidden && !_C.hidden) {
[_A mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(20.0f);
}];
[_C mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.A.mas_right).offset(8.0f);
}];
}
if (_A.hidden && _B.hidden && !_C.hidden) {
[_C mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(8.0f);
}];
}
}
状態枯渇法は非常に暴力的な解決策と見なすことができます。状態枯渇法はさまざまな形式で書かれていますが、全体的な考え方は同じです。枯渇法は理解しやすいですが、欠点は明らかであり、コードの量もあります。過小評価することはできません。、組み合わせを追加するたびに、もう1つの制約スキームが必要です。
一時ビュー変数の記録方法:
一時変数の記録方法は、一時変数のレコードを使用して、ビューの制約を確立することです。具体的なコード例を以下に示します。
- (void)loseConstraintsAction {
UIView *lastView = self.view;
if (!_A.hidden) {
[_A mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo([lastView isEqual:self.view] ? lastView : lastView.mas_right).offset(20.0f);
}];
lastView = _A;
}
if (!_B.hidden) {
[_B mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo([lastView isEqual:self.view] ? lastView : lastView.mas_right).offset(8.0f);
}];
lastView = _B;
}
if (!_C.hidden) {
[_C mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo([lastView isEqual:self.view] ? lastView : lastView.mas_right).offset(8.0f);
}];
}
}
徹底的な方法と比較して、コード構造は大幅に改善されていますが、全体的なコードは依然として人々の満足度を低下させます。
このことから、Sao Dongは、このフローティング効果を実現するためにMasonryに基づくライブラリをカプセル化できるかどうか疑問に思いましたか?そこで、MasonryベースのフローティングレイアウトMasonryFloatLayoutをカプセル化しました。
実装について説明する前に、パッケージ化されたMasonryFloatLayoutの使用方法を見てみましょう。
MasonryFloatLayoutの使用
- 次の図に示すように、最初にデモでMasonryFloatLayoutフォルダーをインポートします。
- ここで変更する必要があるのは、UIViewFloatLayoutHeaderのMasonryのファイルパスアドレスです。エラーが報告された場合は、正しいファイルパスアドレスをインポートしてください。
#ifndef UIViewFloatLayoutHeader_h
#define UIViewFloatLayoutHeader_h
#import "Masonry/Masonry.h"
#endif /* UIViewFloatLayoutHeader_h */
- 必要なViewControllerまたはViewにヘッダーファイルを導入します。
#import "NSArray+FloatLayout.h"
- 3つのビューがあり、フローティングレイアウトを実行する必要があるとすると、最初に初期化作業を完了する必要があります。もちろん、ビュープロパティの宣言と遅延読み込みビューメソッドの実装を含めて、習慣に従うことができます。
@property (nonatomic, strong) UIView *firstView;
@property (nonatomic, strong) UIView *secondView;
@property (nonatomic, strong) UILabel *thirdView;
- (UIView *)firstView {
if (_firstView == nil) {
_firstView = [[UIView alloc] initWithFrame:CGRectZero];
_firstView.backgroundColor = [UIColor redColor];
}
return _firstView;
}
- (UIView *)secondView {
if (_secondView == nil) {
_secondView = [[UIView alloc] initWithFrame:CGRectZero];
_secondView.backgroundColor = [UIColor orangeColor];
}
return _secondView;
}
- (UILabel *)thirdView {
if (_thirdView == nil) {
_thirdView = [[UILabel alloc] initWithFrame:CGRectZero];
_thirdView.backgroundColor = [UIColor blueColor];
_thirdView.textColor = [UIColor whiteColor];
_thirdView.text = @"333333333333";
}
return _thirdView;
}
- 次に、フローティング制約レイアウトを追加する必要があります。石積みレイアウトと同様に、最初
mas_remakeFloatLayoutConstraints
に各ビューに特定のレイアウトを追加する必要があります。最後に、配列を使用してフローティングレイアウトを追加します。具体的なコードは次のとおりです。
[self.firstView mas_remakeFloatLayoutConstraints:^(MASConstraintMaker * _Nonnull make, UIView * _Nonnull lastView, UIView * _Nonnull nextView) {
make.left.equalTo(@50);
make.height.equalTo(@100);
make.width.equalTo(@100);
make.lastFloatConstraint.offset(10.0f);
make.nextFloatConstraint.offset(-10.0f).priorityHigh();
}];
[self.secondView mas_remakeFloatLayoutConstraints:^(MASConstraintMaker * _Nonnull make, UIView * _Nonnull lastView, UIView * _Nonnull nextView) {
make.left.equalTo(@50);
make.height.equalTo(@100);
make.width.equalTo(@100);
make.lastFloatConstraint.offset(30.0f).priorityLow();
make.nextFloatConstraint.offset(-10.0f);
}];
[self.thirdView mas_remakeFloatLayoutConstraints:^(MASConstraintMaker * _Nonnull make, UIView * _Nonnull lastView, UIView * _Nonnull nextView) {
make.left.equalTo(@50);
make.height.equalTo(@100);
make.lastFloatConstraint.offset(10.0f);
make.nextFloatConstraint.offset(-10.0f);
}];
[@[self.thirdView, self.firstView, self.secondView] mas_remakeFloatLayoutConstraintsWithOrientation:FloatLayoutOrientationBottomToTop needLastConstraint:need];
- 上記のプロセスの追加の制約では、私たちが使用する必要がある
lastFloatConstraint
とnextFloatConstraint
これら二つの性質が由来している、MASConstraintMaker + FloatLayout、我々は次のビュービューとこれら二つの属性を隔てを追加することができます。
@property (nonatomic, strong) MASFloatLayoutConstraint *lastFloatConstraint;
@property (nonatomic, strong) MASFloatLayoutConstraint *nextFloatConstraint;
- もちろん、この場合、間隔の関係で優先度を設定することもできます。間隔の制約が競合する場合は、この問題を解決するために優先度を設定します。これは、上記の例にも反映されています。
- (MASFloatLayoutConstraint * (^)(MASLayoutPriority priority))priority;
- (MASFloatLayoutConstraint * (^)(void))priorityLow;
- (MASFloatLayoutConstraint * (^)(void))priorityMedium;
- (MASFloatLayoutConstraint * (^)(void))priorityHigh;
mas_remakeFloatLayoutConstraints
メソッドのBlockパラメーターは、一般的なビューに加えて、MASConstraintMaker *make
前のビューlastView
と次のビューを返しnextView
ますnil
。もちろん、これら2つのパラメーターは。
typedef void(^FloatConstraintMaker)(MASConstraintMaker *make, UIView *lastView, UIView *nextView);
- 各ビューの制約を追加した後、フローティングレイアウトを追加します。フローティングレイアウトは
NSArray
分類に基づいていNSArray+FloatLayout
ます。このmas_remakeFloatLayoutConstraintsWithOrientation
方法には合計2つのパラメータがあります。1つはフロートの方向を設定する方法で、もう1つはフロートの方向を設定する方法です。最後のビューと親。ビュー間の関係は、前のモジュールで説明した2番目のケースと同様です。
typedef enum : NSUInteger {
FloatLayoutOrientationUnknow, // 未知或者根据自定义的约束进行约束布局
FloatLayoutOrientationLeftToRight, // 从左到右进行布局
FloatLayoutOrientationRightToLeft, // 从右到左进行布局
FloatLayoutOrientationTopToBottom, // 从上到下进行布局
FloatLayoutOrientationBottomToTop, // 从下到上进行布局
} FloatLayoutOrientation;
/// 执行浮动布局
/// @param orientation 相对于父视图的浮动方向
/// @param needLastConstraint 是否需要添加最后的约束
- (void)mas_remakeFloatLayoutConstraintsWithOrientation:(FloatLayoutOrientation)orientation
needLastConstraint:(BOOL)needLastConstraint;
全体的な使用プロセスは次のようになります。全体として、元のMasonryレイアウトコードと大きな違いはありません。具体的な例については、私のデモを参照してください。
総括する
使用中に問題が発生した場合は、お気軽にご連絡ください。サンドンがお礼を申し上げます。