QNYGKit
iOS Dynamic Layout Framework Based on Yoga.
QNYGKit framework github address
What is Yoga?
Yoga is a cross-platform layout engine that implements Flexbox specification. It is implemented in c language with high efficiency.
What is FlexBox?
flexible box modules (currently recommended as w3c candidates) are designed to provide a more efficient way to arrange, align and distribute content between containers, even if their size is unknown or dynamic.
The main idea of flexible layout is to enable containers to change the width and height of subitems to fill the available space (mainly to accommodate all types of display devices and screen sizes).
Characteristics of QNYGKit
- Based on Yoga implementation and FlexBox protocol, it has high performance and low intrusiveness to the project.
- QNLayout easy layout, support chain operation, virtual view Div, asynchronous size calculation, multiple ways to calculate size, layout cache and failure
- Implementation of compatible UITableView based on Protocol
Examples of QNYGKit
// // ViewController.m // QNYGKit // // Created by jayhuan on 2018/9/21. // Copyright © 2018 jayhuan. All rights reserved. // #import "ViewController.h" #import "QNFlexBoxLayout.h" #import "UIView+ZJ.h" #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 1. Adaptive, length and height are not limited, similar to sizeToFit. UILabel *labelA = [[UILabel alloc] initWithFrame:CGRectZero]; labelA.numberOfLines = 0; labelA.text = @"1,Adaptive, length and height are not limited. (I am supplementary, I am supplementary, I am supplementary.)"; labelA.backgroundColor = [UIColor orangeColor]; [self.view addSubview:labelA]; [labelA qn_layoutWithWrapContent]; labelA.top = 75; // 2. Adaptive, fixed length and unlimited height. UILabel *labelB = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 0)]; labelB.numberOfLines = 0; labelB.text = @"2,Adaptive, fixed length, unlimited height. (I am supplementary, I am supplementary, I am supplementary.)"; labelB.backgroundColor = [UIColor orangeColor]; [self.view addSubview:labelB]; [labelB qn_layoutWithFixedWidth]; labelB.top = labelA.bottom + 10; // 3. Adaptive, fixed height and unlimited length. UILabel *labelC = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 50)]; labelC.numberOfLines = 0; labelC.text = @"3,Adaptive, fixed height, unlimited length. (I am supplementary, I am supplementary, I am supplementary.)"; labelC.backgroundColor = [UIColor orangeColor]; [self.view addSubview:labelC]; [labelC qn_layoutWithFixedHeight]; labelC.top = labelB.bottom + 10; // 4. Fixed size directly. UILabel *labelD = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 42)]; labelD.numberOfLines = 0; labelD.text = @"4,Direct fixation size. (I am supplementary, I am supplementary, I am supplementary."; labelD.backgroundColor = [UIColor orangeColor]; [self.view addSubview:labelD]; [labelD qn_layoutWithFixedSize]; labelD.top = labelC.bottom + 10; // 5. Combination view, horizontal and vertical layout, etc. UIView *mView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 0)]; mView.backgroundColor = [UIColor yellowColor]; UILabel *labelTitle = [[UILabel alloc] initWithFrame:CGRectZero]; labelTitle.numberOfLines = 0; labelTitle.text = @"5,Combination layout: I am the title, I am the title, I am the title. No limit of rows, no limit of rows, no limit of rows."; labelTitle.backgroundColor = [UIColor orangeColor]; [labelTitle qn_makeLayout:^(QNLayout *layout) { layout.wrapContent(); // Adaptive size layout.margin.equalToEdgeInsets(UIEdgeInsetsMake(0, 0, 10, 0)); }]; QNLayoutDiv *imageDiv = [QNLayoutDiv linerLayoutDiv]; UIImageView *imageViewA = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 124, 78)]; imageViewA.image = [UIImage imageNamed:@"moment_picA"]; [imageViewA qn_makeLayout:^(QNLayout *layout) { layout.wrapSize(); // Fixed size, same effect as imageViewB below }]; UIImageView *imageViewB = [[UIImageView alloc] initWithFrame:CGRectZero]; imageViewB.image = [UIImage imageNamed:@"moment_picB"]; [imageViewB qn_makeLayout:^(QNLayout *layout) { layout.size.equalToSize(CGSizeMake(124, 78)); }]; UIImageView *imageViewC = [[UIImageView alloc] initWithFrame:CGRectZero]; imageViewC.image = [UIImage imageNamed:@"moment_picC"]; [imageViewC qn_makeLayout:^(QNLayout *layout) { layout.size.equalToSize(CGSizeMake(124, 78)); }]; [imageDiv qn_makeLayout:^(QNLayout *layout) { layout.flexDirection.equalTo(@(QNFlexDirectionRow)); // Horizontal layout layout.justifyContent.equalTo(@(QNJustifySpaceBetween)); // Distributed arrangement, evenly spaced layout.children(@[imageViewA, imageViewB, imageViewC]); // Setting Subview }]; [mView qn_makeLayout:^(QNLayout *layout) { layout.flexDirection.equalTo(@(QNFlexDirectionColumn)); // Vertical layout layout.padding.equalToEdgeInsets(UIEdgeInsetsMake(15, 15, 10, 15)); layout.children(@[labelTitle, imageDiv]); }]; [mView addSubview:labelTitle]; [mView addSubview:imageViewA]; [mView addSubview:imageViewB]; [mView addSubview:imageViewC]; [self.view addSubview:mView]; [mView qn_layoutWithFixedWidth]; mView.top = labelD.bottom + 20; } @end