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
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
// 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
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
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
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
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
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.
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