MasonryFloatLayout: diseño flotante basado en mampostería


Prefacio


El uso de Masonry para el diseño en iOS es una operación diaria, pero cuando es similar al diseño flotante de una página web, el diagrama específico es el siguiente.

Quite uno de los elementos y los elementos restantes se moverán en una dirección determinada. En el lado web, este método de diseño se denomina diseño flotante.

Además, existe la siguiente situación: aunque también es flotante, la relación de restricción todavía se mantiene en el otro lado. Esta es también una situación de restricción relativamente común en iOS.

Usar Masonry en iOS para implementar el proceso anterior es realmente muy problemático.Si nos basamos en Masonry, basándonos en esta situación, generalmente tenemos dos formas de escritura, una es el método exhaustivo de estado y la otra es la grabación de variable de vista temporal método.

Legislación estatal exhaustiva:

El método exhaustivo de estado es enumerar todas las combinaciones de vistas y agregar el diseño de restricción correspondiente. Para ejemplos específicos, puede ver el siguiente código.

- (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);
        }];
    }
}

El método de agotamiento del estado puede considerarse una solución muy violenta. El método de agotamiento del estado está escrito en varias formas, pero la idea general es la misma. Aunque el método de agotamiento es simple de entender, las desventajas son obvias y la cantidad de código no se puede subestimar., Cada vez que agregamos una combinación, necesitamos un esquema de restricción más ...


Método de grabación de variable de vista temporal:

El método de registro de variable temporal es utilizar un registro de variable temporal para establecer restricciones con respecto a qué vista. El ejemplo de código específico se muestra a continuación.

- (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);
        }];
    }
}

En comparación con el método exhaustivo, la estructura del código se ha mejorado mucho, pero el código general aún hace que las personas se sientan menos satisfechas.

A partir de esto, Sao Dong se preguntó si era posible encapsular una biblioteca basada en Masonry para lograr este efecto flotante, así que encapsulé un diseño flotante basado en Masonry MasonryFloatLayout .

Antes de hablar sobre la implementación, echemos un vistazo a cómo usar el MasonryFloatLayout empaquetado .


MasonryFloatLayout uso


  • Primero importe la carpeta MasonryFloatLayout en Demo , como se muestra en la siguiente figura.

  • Lo que debe cambiarse aquí es la dirección de ruta de archivo de Masonry of UIViewFloatLayoutHeader . Si se informa un error, importe la dirección de ruta de archivo correcta.
#ifndef UIViewFloatLayoutHeader_h
#define UIViewFloatLayoutHeader_h

#import "Masonry/Masonry.h"

#endif /* UIViewFloatLayoutHeader_h */
  • Introduzca el archivo de encabezado en el ViewController o View requerido.
#import "NSArray+FloatLayout.h"
  • Supongamos que ahora tenemos tres Vistas y necesitamos realizar un diseño flotante, entonces primero debemos completar el trabajo de inicialización. Incluyendo la declaración de las propiedades de la Vista y la implementación de los métodos de Vista de carga diferida, por supuesto, puede seguir sus hábitos.
@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;
}
  • A continuación, debemos agregar el diseño de restricción flotante. Al igual que el diseño de mampostería, primero debemos mas_remakeFloatLayoutConstraintsagregar un diseño específico a cada Vista. Finalmente, use una matriz para agregar un diseño flotante. El código específico es el siguiente.
    [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];
  • En el proceso anterior agregue restricciones, necesitamos usar lastFloatConstrainty nextFloatConstraint, estas dos propiedades se derivan de MASConstraintMaker + FloatLayout , podemos agregar una relación espaciada con la siguiente Vista Vista y por estos dos atributos.
@property (nonatomic, strong) MASFloatLayoutConstraint *lastFloatConstraint;

@property (nonatomic, strong) MASFloatLayoutConstraint *nextFloatConstraint;
  • Por supuesto, la relación de espaciado también puede establecer la prioridad, en este caso. Si hay un conflicto de restricción de espaciado, establezca la prioridad para resolver este problema. Esto también se refleja en el ejemplo anterior.
- (MASFloatLayoutConstraint * (^)(MASLayoutPriority priority))priority;

- (MASFloatLayoutConstraint * (^)(void))priorityLow;

- (MASFloatLayoutConstraint * (^)(void))priorityMedium;

- (MASFloatLayoutConstraint * (^)(void))priorityHigh;
  • mas_remakeFloatLayoutConstraintsEl parámetro Bloque del método MASConstraintMaker *makedevolverá la vista anterior lastViewy la vista siguiente además de las comunes. Por nextViewsupuesto, estos dos parámetros pueden ser nil.
typedef void(^FloatConstraintMaker)(MASConstraintMaker *make, UIView *lastView, UIView *nextView);
  • Después de agregar las restricciones de cada vista, agregamos el diseño flotante. El diseño flotante se basa en NSArrayla clasificación NSArray+FloatLayout. El mas_remakeFloatLayoutConstraintsWithOrientationmétodo tiene un total de dos parámetros. Uno es establecer la dirección del flotador y el otro es establecer el última vista y el padre La relación entre vistas es similar al segundo caso mencionado en el módulo anterior.
typedef enum : NSUInteger {
    FloatLayoutOrientationUnknow,      // 未知或者根据自定义的约束进行约束布局
    FloatLayoutOrientationLeftToRight, // 从左到右进行布局
    FloatLayoutOrientationRightToLeft, // 从右到左进行布局
    FloatLayoutOrientationTopToBottom, // 从上到下进行布局
    FloatLayoutOrientationBottomToTop, // 从下到上进行布局
} FloatLayoutOrientation;

/// 执行浮动布局
/// @param orientation 相对于父视图的浮动方向
/// @param needLastConstraint 是否需要添加最后的约束
- (void)mas_remakeFloatLayoutConstraintsWithOrientation:(FloatLayoutOrientation)orientation
                                     needLastConstraint:(BOOL)needLastConstraint;

El proceso de uso general es así. En general, no hay mucha diferencia con el código de diseño original de Masonry. Para ejemplos específicos, consulte mi Demo .


para resumir


Si tiene algún problema durante el uso, no dude en ponerse en contacto conmigo, Sao Dong está aquí para agradecerles a todos.

Portal de mamposteríaFloatLayout

Supongo que te gusta

Origin blog.csdn.net/qq_33591200/article/details/115291655
Recomendado
Clasificación