NerdyUI

The best use of the quick layout UI library for iOS 8 and later. Making: github.com/nerdycat/Ne…


The preface

As we all know, UI accounts for a large proportion in an App. If UI can be laid out quickly, the overall development efficiency of App will be greatly improved. NerdyUI was created for this reason.

NerdyUI uses a very compact chain syntax, provides some commonly used but missing functionality in system controls, a simpler way to create constraints, and a better understanding of the layout system, which is bound to greatly reduce your code and development time.


Quickly create NSString, UIFont, UIColor, UIImage and commonly used structs

You can use Str() to convert most types to NSString. Similarly, you can print most variables in Log().

Str(100);                     / / @ "100"
Str(3.14);                    / / @ "3.14"
Str(@0.618);                  / / @ "0.618"
Str(view.frame);              / / @ "{{0, 0}, {100, 100}}"
Str(view.center);             / / @ "50, 50}"
Str(_cmd);                    //@"viewDidLoad"
Str(NSString.class);          //@"NSString"
Str("c string");              //@"c string"
Str(@"1 + 1 = %d".1 + 1);    //@"1 + 1 = 2

Log(100);
Log(3.14);
Log(@0.618);
Log(view.frame); .Log(@"1 + 1 = %d".1 + 1);

// Concatenates a string
@"1".a(@"2").a(3).a(nil).a(4.0f).a(@5).a(@"%d".6);    / / @ "123456"Copy the code

You can create an NSAttributedString with AttStr().

AttStr(@"hello, 101").match(@"[0-9] +").underline;
AttStr(@"A smile ", Img(@"smile"), @"!!!!!");        //attributedString with image attachmentCopy the code

You can create UIFont with Fnt().

Fnt(15);                     //[UIFont systemFontOfSize:15]
Fnt(@ 15);                    //[UIFont boldSystemFontOfSize:15]
Fnt(@"body");                //UIFontTextStyleBody
Fnt(@"Helvetica,15");        //helvetica font with size 15Copy the code

You can create UIColor with Color().

Color(@"red");                //[UIColor redColor]
Color(@"Green, 0.5");          // Green color with 0.5 alpha
Color(@"0,0,255");            //blue color
Color(@"#0000FF");            //blue color
Color(@"0.5 # 00 f,");           // Blue color with 0.5 alpha
Color(@"random");             //random colorCopy the code

You can create UIImage with Img().

Img(@"imageName");            //[UIImage imageNamed:@"imageName"]
Img(@"#imageName");           // A # sign will return a stretchable image
Img(@"red");                  // Return a red image of 1x1 sizeCopy the code

You can create CGPoint, CGSize, CGRect, NSRange, UIEdgeInsets with XY(), WH(), XYWH(), Range(), Insets().

CGPoint        p = XY(20.20);
CGSize         s = WH(50.50);

CGRect        f1 = XYWH(20.20.50.50);
CGRect        f2 = XYWH(f1.origin, f1.size);
CGRect        f3 = XYWH(f2.origin, 50.50);
CGRect        f4 = XYWH(20.20, f3.size);

NSRange        r = Range(10.20);

UIEdgeInsets i1 = Insets(10);                / / {10, 10, 10, 10}
UIEdgeInsets i2 = Insets(10.20);            / / {10, 20, 10, 20}
UIEdgeInsets i3 = Insets(10.20.30);        / / {10, 20, 30, 20}
UIEdgeInsets i4 = Insets(10.20.30.40);    / / {10, 20, 30, 40}Copy the code

Using these macros simplifies the creation of some common types, and more importantly you can set the view’s property values in the same way, which you’ll see later.

Quick access to the frame property and screen size

someView.x = 10;
someView.y = someView.x;
someView.xy = XY(10.10);
someView.w = 50;                //width
someView.h = someView.w;        //height
someView.wh = WH(50.50);
someView.frame = XYWH(10.10.50.50);

someView.cx = 25;
someView.cy = someView.cx;
someView.center = XY(25.25);

someView.maxX = 60;
someView.maxY = someView.maxX;
someView.maxXY = XY(60.60);

//Screen is just the macro definition for [UIScreen mainScreen]
someView.wh = WH(Screen.width, Screen.height);Copy the code

I guess most people have similar extensions

Create UI controls quickly

NerdyUI uses chained syntax to quickly create and set up UI controls.

UIView *view1 = View.xywh(20.30.50.50).bgColor(@"red").opacity(0.7).border(3The @"3d3d3d");
UIView *view2 = View.xy(80.30).wh(view1.wh).bgColor(@"Blue, 0.7").cornerRadius(25).shadow(0.8).onClick(^{
    Log(@"view2");
});Copy the code




view

UIImageView *moose = ImageView.img(@"moose").x(20).y(100).shadow(0.6.2.- 3.- 1);
UILabel *quiz = Label.str(@"%d+%d=?".1.1).fnt(@17).color(@"66,66,66").fitSize.x(moose.maxX + 10).cy(moose.cy);Copy the code




moose

// If you don't need to access the title attribute later, defining it as id can save some code
id title = AttStr(@"TAP ME").fnt(15).underline.range(0.3).fnt(@18).color(@"random");
UIButton *button1 = Button.str(title).insets(5.10).fitSize.border(1).xy(20.150).onClick(^(UIButton *btn) {
    Exp() executes arbitrary code anywhere
    quiz.text = Str(@"%d+%d=%d".1.1, Exp(btn.tag += 1)); 
    [quiz sizeToFit];
});

UIButton *button2 = Button.str(@"HAT").highColor(@"brown").img(@"hat").gap(8);
button2.xywh(button1.frame).x(button1.maxX + 10).cornerRadius(5).bgImg(@"Blue, 0.5").highBgImg(@"orange");
/ /. HighBgImg () can be used to set the UIButton highlightedBackgroundColor, this is a very useful functionCopy the code




button

id pinField = TextField.x(button1.x).y(button1.maxY + 15).wh(170.30).onChange(^(NSString *text) {
    // Here self has already done weakify automatically, don't worry about reference loops
    [(id)[self.view viewWithTag:101] setText:text];
}).numberKeyboard.maxLength(4).hint(@"pin code").fnt(15).roundStyle;

id textView = TextView.xywh(20.240.170.100).border(1).insets(8).hint(@"placeholder").fnt([pinField font]).tg(101);Copy the code




input

As you can see, most of the chain properties are fairly straightforward. Some properties are very flexible and can accept different types of parameters. By the way, View is just the macro definition of [UIView New], and everything else is the same.

You can set the view’s alpha and tag values using.opacity() and.tg().

. You can use. (x), y (),, xy (), w (),, h (), wh (), the xywh (),, cx (), cy (), the cxy (), the maxX (), the maxY (), the maxXY () to set up the view of the size and location.

You can use.touchEnabled,.touchDisabled,.invisible to set whether a view is clickable or visible.

You can use.flexibleleft,.flexibleright,.flexibletop,.flexiblebottom,.flexiblelr,.flexibletb,.flexiblelrtb, .flexibleWidth,.flexibleheight,.flexibleWh, etc to set autoresizingMask.

You can set fonts with.fnt(), which takes the same parameters as FNT ().

You can set text or attribtedText with.str(), which takes the same arguments as STR ().

You can use.img(),.highimg (),.bgimg () and.highbgimg () to set image, highlightedImage, The backgroundImage and highlightedBackgroundImage. They accept the same parameters as Img().

You can use.tint(),.color(),.bgColor(),.highcolor () to set tintColor, textColor, backgroundColor and highlightedTextColor, They accept the same parameters as Color().

You can set borders and shadows with.border(),.cornerradius () and.shadow().

You can use.fitWidth,.fitheight, and.fitSize to change the size of the view so that it is just the size to contain the view’s contents.

You can add a click event to any view with.onclick ().

For UITextField and UITextView, you can use.hint() to set placeholder,.maxLength() to limit the length of input text, and.onchange () to add a text change event.

If it’s UIButton, UITextField, or UITextView, you can also use.insets() to add some padding.

The attributes listed here are just a few. You can see the full list of attributes in the corresponding extension header.

UILabel extension

Previously, if you wanted to add line spacing to UILabel, you had to use NSAttributedString. Now you just need to set it with.linegap ().

Another great extension is linking. You just use AttStr() to create an NSAttributedString and mark part of it as.linkForLabel, and that part of the tag automatically becomes a link. Then you just need to add a link click event to UILabel with.onlink ().

id str = @"Lorem ipsum 20 dolor sit er elit lamet, consectetaur cillium #adipisicing pecu, sed do #eiusmod tempor incididunt ut labore et 3.14 dolore magna aliqua.";
id attStr = AttStr(str).range(0.5).match(@"lamet").match(@"[0-9.]+").matchHashTag.linkForLabel;

Label.str(attStr).multiline.lineGap(10).xywh(self.view.bounds).onLink(^(NSString *text) {
    Log(text);
}).addTo(self.view);Copy the code




label

Create constraints quickly

Sometimes it can be cumbersome to manually modify a frame. NerdyUI provides chained properties and a similar way to navigation for creating constraints.

You can add width and height constraints with.fixWidth(),.fixheight (),.fixwh ().

You can embed a view into its parent view using.embedin (), which adds up, down, left, and right constraints.

You can use.horhugging (),.horresistance (),.verhugging (),.verresistance (),.lowhugging,.lowresistance, . HighHugging and. HighResistance to set contentHuggingPriority and contentCompressionResistancePriority. When you have multiple views in a StackView, you can use these properties to set which views can and cannot be stretched.

For more complex constraints, you can set them with.makecons (),.remakecons (), and.updatecons (), just like you would with navigation.

ImageView.img(@"macbook").embedIn(self.view).centerMode;

id hello = Label.str(@"HELLO").fnt(@20).wh(80, 80).centerAlignment;
id mac = Label.str(@"MAC").fnt(@20).wh(80, 80).centerAlignment;

Before using.makecons (), you must add the current view to the superview, using.addto ()
EffectView.darkBlur.fixWH(80, 80).addTo(self.view).makeCons(^{
    // In.makecons () you can use the make variable directly without having to explicitly define it
    make.right.equal.superview.centerX.constants(0);
    make.bottom.equal.superview.centerY.constants(0);
}).addVibrancyChild(hello).tg(101);

EffectView.extraLightBlur.fixWidth(80).fixHeight(80).addTo(self.view).makeCons(^{
    make.left.bottom.equal.view(self.view).center.constants(0, 0);
});

EffectView.lightBlur.addTo(self.view).makeCons(^{
    make.size.equal.constants(80, 80).And.center.equal.constants(40, 40);
}).addVibrancyChild(mac);

id subImg = Img(@"macbook").subImg(95, 110, 80, 80).blur(10);
ImageView.img(subImg).addTo(self.view).makeCons(^{
    make.centerX.top.equal.view([self.view viewWithTag:101]).centerX.bottom.constants(0);
});Copy the code




constraints

A quick layout

Manually adding constraints to each view can be cumbersome after a moment’s thought. Fortunately, most of the UI can be implemented using HorStack() and VerStack(). With these two simplified stackViews, plus the properties described above, many times you don’t need to manually display any constraints at all.

_indexLabel = Label.fnt(17).color(@"darkGray").fixWidth(44).centerAlignment;
_iconView = ImageView.fixWH(64.64).cornerRadius(10).border(Screen.onePixel, @"#CCCCCC");

// Set the preferredMaxLayoutWidth with.preferwidth () to help improve performance
_titleLabel = Label.fnt(15).lines(2).preferWidth(Screen.width - 205);
_categoryLabel = Label.fnt(13).color(@"darkGray");

_ratingLabel = Label.fnt(11).color(@"orange");
_countLabel = Label.fnt(11).color(@"darkGray");

_actionButton = Button.fnt(@15).color(@"#0065F7").border(1The @"#0065F7").cornerRadius(3);
_actionButton.highColor(@"white").highBgImg(@"#0065F7").insets(5.10);
_iapLabel = Label.fnt(9).color(@"darkGray").lines(2).str(@"In-App\nPurchases").centerAlignment;

//.gap() adds gaps between each StackView Item
id ratingStack = HorStack(_ratingLabel, _countLabel).gap(5);
id midStack = VerStack(_titleLabel, _categoryLabel, ratingStack).gap(4);
id actionStack = VerStack(_actionButton, _iapLabel).gap(4).centerAlignment;

HorStack(
         _indexLabel,
         _iconView,
         @10.// Use NSNumber to add gaps between two items
         midStack,
         NERSpring,     //NERSpring is a special variable that acts as a spring to keep the actionStack on the far right
         actionStack
).embedIn(self.contentView, 10.0.10.15);Copy the code




appcell

Here we create a similar Cell that mimics the AppStore charts. You can see that HorStack and VerStack are very simple to use. You just need to find the smallest Stack, embed it in the upper Stack, and repeat the process until the outermost Stack is inserted into its superview using embedIn. Finally, you can add gaps to these views.

Use “Debug View Hierarchy” to see how these views are nested together.





appcell2

Once the layout is complete, all that’s left is to set up what to display, and nothing else needs to be done.

Lightweight Style

Most chain properties can be set to style.

/ / the global Style
Style(@"h1").color(@"# 333333").fnt(17);
Style(@"button").fixHeight(30).insets(0.10).cornerRadius(5);
/ / local Style
id actionButtonStyle = Style().styles(@"button h1").bgImg(@"red").highBgImg(@"blue").highColor(@"white");Copy the code

Here we create two global styles and a local Style. Local styles use.styles() to inherit those two global styles. Once created, global styles can be referenced globally by Style names, and local styles can only be referenced by variable names. All UIViews (and their subclasses) and NSAttributedString can reference these styles.

id foo = Label.styles(@"h1").str(@"hello world");
id bar = Button.styles(actionButtonStyle).str(@"Send Email");Copy the code

other

You can use PlainTV and GroupTV to create static UITableViews, such as Settings pages.

PlainTV(Row.str(@"Row1"), Row.str(@"Row2"), Row.str(@"Row3")).embedIn(self.view);Copy the code

You can create and display UIAlert and UIActionSheet with Alert and ActionSheet.

Alert.title(@"Title").message(@"Message").action(@"OK",^{}), cancel(@"Cancel").show(a);ActionSheet.title(@"Title").message(@"Message").action(@"OK",^{}), cancel(@"Cancel").show(a);Copy the code

For NSArray, we provide.foreach (),.map(),.filter(), and.reduce() chained attributes.

id result = @[@1, @2, @3, @4].map(^(NSInteger n) {
    return n * 2;
}).filter(^(NSInteger n) {
    return n < 5;
}).reduce(^(NSInteger ac, NSInteger n) {
    return ac + n;
});Copy the code

Pay attention to

Using Chinese string constants directly in chained attributes will cause subsequent autocomplete prompts to fail. One solution is to define the Chinese string as a variable by itself, or put.str(),.hint(), and so on at the end.

When you use.onclick (),.onlink (),.onchange () and.onFinish(), the self inside is already weakify handled, so you don’t need to worry about reference loops. Sometimes you might need to make a strong reference to it to make sure it doesn’t get released early. In addition to passing a block, these attributes can also pass a method name as a callback method.

NerdyUI uses a lot of macro definitions and category methods, and doesn’t add any prefixes for ease of use. While all names have been carefully chosen, please note that there may be conflicts with your own code or other third-party libraries.

Use CocoaPods installation

pod "NerdyUI"Copy the code