{"id":1297,"url":"https://github.com/nerdycat/Cupcake","last_synced_at":"2025-08-06T13:32:54.762Z","repository":{"id":56282834,"uuid":"93714146","full_name":"nerdycat/Cupcake","owner":"nerdycat","description":"An easy way to create and layout UI components for iOS (Swift version).","archived":false,"fork":false,"pushed_at":"2020-11-16T23:22:39.000Z","size":784,"stargazers_count":287,"open_issues_count":11,"forks_count":38,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-08-05T14:24:26.650Z","etag":null,"topics":["constraints","layout","nsattributedstring","stackview","static-tableview","swift","ui","uilabel-link"],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nerdycat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-08T06:18:53.000Z","updated_at":"2024-07-28T10:47:26.000Z","dependencies_parsed_at":"2022-08-15T16:00:38.131Z","dependency_job_id":null,"html_url":"https://github.com/nerdycat/Cupcake","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerdycat%2FCupcake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerdycat%2FCupcake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerdycat%2FCupcake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerdycat%2FCupcake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nerdycat","download_url":"https://codeload.github.com/nerdycat/Cupcake/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":215780271,"owners_count":15929791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["constraints","layout","nsattributedstring","stackview","static-tableview","swift","ui","uilabel-link"],"created_at":"2024-01-05T20:15:43.216Z","updated_at":"2024-08-17T16:30:58.789Z","avatar_url":"https://github.com/nerdycat.png","language":"Swift","readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"./res/cupcake.png\" alt=\"cupcake\" width=\"30%\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://camo.githubusercontent.com/987c5cc551bc4988195dffc73b6822e11eb451cc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7377696674342d636f6d70617469626c652d3442433531442e7376673f7374796c653d666c6174\" alt=\"Swift4\" /\u003e\n\u003cimg src=\"https://camo.githubusercontent.com/440edeeeb3b2c1b118c6184fd929167587dea9a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73776966742d352e302d6f72616e67652e737667\" alt=\"Swift5\" /\u003e\n\u003cimg src=\"https://camo.githubusercontent.com/1d276aa371242346c77c3a5b8db34beaa2014722/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f694f532d382e302532422d626c75652e737667\" alt=\"Platform\" /\u003e\n\u003cimg src=\"http://cocoapod-badges.herokuapp.com/v/Cupcake/badge.png\" alt=\"Version\" /\u003e\n\u003cimg src=\"http://cocoapod-badges.herokuapp.com/l/Cupcake/badge.png\" alt=\"License\" /\u003e\n\u003c/p\u003e\n\n## Introduction\nCupcake is a framework that allow you to easily create and layout UI components for iOS 8.0+. It use chaining syntax and provides some frequent used functionalities that are missing in UIKit. \n\n---\n## Easy way to create UIFont, UIImage and UIColor objects\n\t\nYou can create UIFont object with `Font()` function.\n\n\tFont(15)                    //UIFont.systemFontOfSize(15)\n\tFont(\"15\")                  //UIFont.boldSystemFontOfSize(15)\n\tFont(\"body\")                //UIFontTextStyle.body\n\tFont(\"Helvetica,15\")        //helvetica with size of 15\n\t\nYou can create UIImage object with `Img()` function.\n\n\tImg(\"imageName\")            //image with name\n\tImg(\"#imageName\")           //prefixed with # will return a stretchable image\n\tImg(\"$imageName\")           //prefixed with $ will return a template image\n\tImg(\"red\")                  //1x1 size image with red color\n\nYou can create UIColor object with `Color()` function.\n\n\tColor(\"red\")                //UIColor.red\n\tColor(\"0,0,255\")            //RGB color\n\tColor(\"#0000FF\")            //Hex color\n\tColor(\"random\")             //random color\n    \n    Color(\"red,0.5\")            //even with alpha\n    Color(\"0,0,255,0.8\")\n    Color(\"#0000FF,0.5\")\n    Color(\"random,0.2\")\n\t\n    Color(Img(\"pattern\"))       //or image\n\n\n## Easy way to create NSAttributedString objects and String manipulations\n\nYou can create NSAttributedString object with `AttStr()` function.\n\n\tAttStr(\"hello\").color(\"red\")                        //red color string\n\tAttStr(\"hello, 101\").select(\"[0-9]+\").underline     //101 with underline\n\tAttStr(\"A smile \", Img(\"smile\"), \" !!\")             //insert image attachment\n\t\nString manipulations:\n\n\tStr(1024)                                           //convert anything to string\n\tStr(\"1 + 1 = %d\", 2)                                //formatted string\n\t\n\t\"hello world\".subFrom(2).subTo(\"ld\")                //\"llo wor\"\n\t\"hello world\".subAt(1..\u003c4)                          //\"ell\"\n\t\"hello 12345\".subMatch(\"\\\\d+\")                      //\"12345\"\n\n\n## 4 basic UI components\n\nYou can create UIView, UILabel, UIImageView and UIButton objects simply by using `View`, `Label`, `ImageView` and `Button` variables.\n\n\tView.bg(\"red\").border(1).radius(4).shadow(0.7, 2)\n\t\n\tLabel.str(\"hello\\ncupcake\").font(30).color(\"#FB3A9F\").lines(2).align(.center)\n\t\n\tImageView.img(\"cat\").mode(.scaleAspectFit)\n\t\n\tButton.str(\"kitty\").font(\"20\").color(\"#CFC8AC\").highColor(\"darkGray\").onClick({ _ in\n        print(\"click\")\n\t}).img(\"cat\").padding(10).border(1, \"#CFC8AC\")\n\t\nAs you can see, `.font()`, `.img()` and `.color()` can take the same parameters as `Font()`, `Img()` and `Color()`. Also you can pass String, NSAttributedString or any other values to `.str()`.\n\n\n## Enhancements\n\nYou can add click handler and adjust click area to any view.   \nTo round a view with half height no matter what size it is, simply use `.radius(-1)`. \n\n\tImageView.img(\"mario\").radius(-1).touchInsets(-40).onClick({ _ in\n\t    print(\"extending touch area\")\n\t})\n\nYou can add line spacing and link handling to UILabel.\n\n\tlet 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.\"\n\tlet attStr = AttStr(str).select(\"elit\", .number, .hashTag, .range(-7, 6)).link()\n\t\n\tLabel.str(attStr).lineGap(10).lines().onLink({ text in\n\t    print(text)\n\t})\n\t\n`.bg()` allow you to set background for any view with color or image.    \n`.highBg()` allow you to set highlighted background for UIButton (which is very useful).    \nAlso you can add spacing to title and image within button or even exchange their position. \n\n\tButton.str(\"More\").img(\"arrow\").color(\"black\").bg(\"lightGray,0.3\").highBg(\"lightGray\").gap(5).reversed()\n\t\nYou can add placeholder and limit text input to UITextField and UITextView.\n\n\tTextField.hint(\"placeholder\").maxLength(10).padding(0, 10).keyboard(.numberPad)\n\t\n\tTextView.hint(\"placeholder\").maxLength(140).padding(10).onChange({ textView in\n\t    print(textView.text)\n\t})\n    \n\n## Easy way to Setup Constraints\n\nYou use `.pin()` to setup simple constraints relative to self or superview. \n\n\t.pin(200)                       //height constriant\n\t.pin(100, 200)                  //width and height constraints\t\t\t\n\t.pin(.xy(50, 50))               //left and top constraints relative to superview\n\t.pin(.maxXY(50, 50))            //right and bottom constraints relative to superview\n\t.pin(.center)                   //center equals to superview\n\t ...\n\t.pin(.lowHugging)               //low content hugging priority, useful when embed in StackView\n\t.pin(.lowRegistance)            //low content compression resistance priority, useful when embed in StackView\n\n\nYou use `.makeCons()` and `.remakeCons()` to setup any constraints just like SnapKit.\n\n\t.makeCons({\n   \t    $0.left.top.equal(50, 50)\n\t    $0.size.equal(view2).multiply(0.5, 0.7)\n\t})\n\t\n\t.remakeCons({ make in\n\t    make.origin.equal(view2).offset(10, 20)\n\t    make.width.equal(100)\n\t    make.height.equal(view2).multiply(2)\n\t})\n\t\nYou use `.embedIn()` to embed inside superview with edge constriants.\n\n\t.embedIn(superview)                     //top: 0,  left: 0,  bottom: 0,  right: 0\n    .embedIn(superview, 10)                 //top: 10, left: 10, bottom: 10, right: 10\n    .embedIn(superview, 10, 20)             //top: 10, left: 20, bottom: 10, right: 20\n    .embedIn(superview, 10, 20, 30)         //top: 10, left: 20, right: 30\n    .embedIn(superview, 10, 20, 30, 40)     //top: 10, left: 20, bottom: 30, right: 40\n    .embedIn(superview, 10, 20, nil)        //top: 10, left: 20\n\n\n## Easy way to Layout\n\nSetup constraints for every views manually could be tedious. Luckily, you can build most of the layouts by simply using `HStack()` and `VStack()` (which are similar to UIStackView) and hopefully without creating any explicit constirants. \n\n\tindexLabel = Label.font(17).color(\"darkGray\").align(.center).pin(.w(44))\n   \ticonView = ImageView.pin(64, 64).radius(10).border(1.0 / UIScreen.main.scale, \"#CCC\")\n        \n\ttitleLabel = Label.font(15).lines(2)\n\tcategoryLabel = Label.font(13).color(\"darkGray\")\n        \n\tratingLabel = Label.font(11).color(\"orange\")\n\tcountLabel = Label.font(11).color(\"darkGray\")\n        \n\tactionButton = Button.font(\"15\").color(\"#0065F7\").border(1, \"#0065F7\").radius(3)\n\tactionButton.highColor(\"white\").highBg(\"#0065F7\").padding(5, 10)\n        \n\tiapLabel = Label.font(9).color(\"darkGray\").lines(2).str(\"In-App\\nPurchases\").align(.center)\n        \n\tlet ratingStack = HStack(ratingLabel, countLabel).gap(5)\n \tlet midStack = VStack(titleLabel, categoryLabel, ratingStack).gap(4)\n\tlet actionStack = VStack(actionButton, iapLabel).gap(4).align(.center)\n        \n \tHStack(indexLabel, iconView, 10, midStack, \"\u003c--\u003e\", 10, actionStack).embedIn(self.contentView, 10, 0, 10, 15)\n \t\n \u003cimg src=\"./res/appstore.png\" alt=\"appStore\" width=\"50%\" /\u003e\n\n\n## Lightweight Style\n\nSome of the chainable properties can be set as style.\n\n\t//local style\n\tlet style1 = Styles.color(\"darkGray\").font(15)\n\tLabel.styles(style1).str(\"hello world\")\n\t\n\t//global style\n\tStyles(\"style2\").bg(\"red\").padding(10).border(3, \"#FC6560\").radius(-1)\n\tButton.styles(style1, \"style2\").str(\"hello world\")\n\t\n\t//copy style from view\n\tlet style3 = Styles(someButton)\n\tButton.styles(someButton).str(\"hello world\")\n\t\n\n## Others\n\nYou can create static tableView with `PlainTable()` or `GroupTable()` functions.\n\t\n\tlet titles = [\"Basic\", \"Enhancement\", \"Stack\", \"StaticTable\", \"Examples\"]\n\tPlainTable(titles).onClick({ row in\n\t    print(row.indexPath)\n\t})\n\nYou can present `Alert` And `ActionSheet` using the chaining syntax as well.\n\n\tAlert.title(\"Alert\").message(\"message go here\").action(\"OK\").show()\n\t\n\tActionSheet.title(\"ActionSheet\").message(\"message go here\").action(\"Action1\", {\n \t    print(\"Action1\")\n \t}).action(\"Action2\", {\n \t    print(\"Action2\")\n \t}).cancel(\"Cancel\").show()\n\n\n## Installation\n\n### Cocoapods\nCupcake can be added to your project using CocoaPods by adding the following line to your Podfile:\n\n\tpod \"Cupcake\"\n\n### Carthage\nIf you're using Carthage you can add a dependency on Cupcake by adding it to your Cartfile:\n\n\tgithub \"nerdycat/Cupcake\"\n","funding_links":[],"categories":["Layout","Libs","UI","Layout [🔝](#readme)"],"sub_categories":["Other Hardware","Layout","Other free courses"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerdycat%2FCupcake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnerdycat%2FCupcake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerdycat%2FCupcake/lists"}