[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-7067":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":16,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":16,"starSnapshotCount":16,"syncStatus":25,"lastSyncTime":26,"discoverSource":27},7067,"AloeStackView","marlimox\u002FAloeStackView","marlimox","A simple class for laying out a collection of views with a convenient API, while leveraging the power of Auto Layout.","",null,"Swift",2820,167,57,17,0,58.68,"Apache License 2.0",false,"master",[],"2026-06-12 04:00:32","# AloeStackView\n\nA simple class for laying out a collection of views with a convenient API, while leveraging the power of Auto Layout.\n\n[![Carthage compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCarthage-compatible-4BC51D.svg?style=flat)](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage)\n[![Version](https:\u002F\u002Fimg.shields.io\u002Fcocoapods\u002Fv\u002FAloeStackView.svg)](https:\u002F\u002Fcocoapods.org\u002Fpods\u002FAloeStackView)\n[![License](https:\u002F\u002Fimg.shields.io\u002Fcocoapods\u002Fl\u002FAloeStackView.svg)](https:\u002F\u002Fcocoapods.org\u002Fpods\u002FAloeStackView)\n[![Platform](https:\u002F\u002Fimg.shields.io\u002Fcocoapods\u002Fp\u002FAloeStackView.svg)](https:\u002F\u002Fcocoapods.org\u002Fpods\u002FAloeStackView)\n\n## Introduction\n\n`AloeStackView` is a class that allows a collection of views to be laid out in a vertical or horizontal list. In a broad\nsense, it is similar to `UITableView`, however its implementation is quite different and it makes a different set of\ntrade-offs.\n\n`AloeStackView` focuses first and foremost on making UI very quick, simple, and straightforward to implement. It\ndoes this in two ways:\n\n* It leverages the power of Auto Layout to automatically update the UI when making changes to views.\n\n* It forgoes some features of `UITableView`, such as view recycling, in order to achieve a much simpler and safer API.\n\nWe've found `AloeStackView` to be a useful piece of infrastructure and hope you find it useful too!\n\n## Table of Contents\n\n* [Features](#features)\n* [System Requirements](#system-requirements)\n* [Example App](#example-app)\n* [Usage](#usage)\n  - [Creating an AloeStackView](#creating-an-aloestackview)\n  - [Adding, Removing, and Managing Rows](#adding-removing-and-managing-rows)\n  - [Handling User Interaction](#handling-user-interaction)\n  - [Dynamically Changing Row Content](#dynamically-changing-row-content)\n  - [Styling and Controlling Separators](#styling-and-controlling-separators)\n  - [Extending AloeStackView](#extending-aloestackview)\n  - [When to use AloeStackView](#when-to-use-aloestackview)\n* [Installation](#installation)\n* [Contributions](#contributions)\n* [Maintainers](#maintainers)\n* [Contributors](#contributors)\n* [License](#license)\n* [Why is it called AloeStackView?](#why-is-it-called-aloestackview)\n\n## Features\n\n* Allows you to keep strong references to views and dynamically change their properties, while Auto Layout\nautomatically keeps the UI up-to-date.\n\n* Allows views to be dynamically added, removed, hidden and shown, with optional animation.\n\n* Includes built-in support for customizable separators between views.\n\n* Provides an extensible API, allowing specialized features to be added without modifying `AloeStackView` itself.\n\n* Widely used and vetted in a highly-trafficked iOS app.\n\n* Small, easy-to-understand codebase (under 600 lines of code) with no external dependencies keeps binary size\nincrease to a minimum and makes code contributions and debugging painless.\n\n## System Requirements\n\n* Deployment target iOS 9.0+\n* Xcode 10.0+\n* Swift 4.0+\n\n## Example App\n\nThe repository includes a simple [example iOS app](Example).\n\nYou can try it out by cloning the repo, opening `AloeStackViewExample.xcworkspace`, and running the app.\n\nThe example app shows a few ways `AloeStackView` can be used to implement a screen in an iOS app.\n\n![Example app](Docs\u002FImages\u002Fexample_app.gif)\n\n## Usage\n\n### Creating an AloeStackView\n\nThe primary API is accessed via the `AloeStackView` class.\n\nYou can create an instance of `AloeStackView` quite easily in your code:\n\n```swift\nimport AloeStackView\n\nlet stackView = AloeStackView()\n```\n\n`AloeStackView` is a `UIView` (specifically a `UIScrollView`), and thus can be used in the same way as any other\nview in your app.\n\nAlternatively, if you want to build an entire `UIViewController` using `AloeStackView`, you can use the convenient\n`AloeStackViewController` class:\n\n```swift\nimport AloeStackView\n\npublic class MyViewController: AloeStackViewController {\n\n  public override func viewDidLoad() {\n    super.viewDidLoad()\n    stackView.addRow(...)\n  }\n\n}\n```\n\n`AloeStackViewController` is very similar to classes such as `UITableViewController` and\n`UICollectionViewController` in that it creates and manages an `AloeStackView` for you. You can access the\n`AloeStackView` via the `stackView` property. Using `AloeStackViewController` rather than creating your own\n`AloeStackView` inside a `UIViewController` simply saves you some typing.\n\n### Adding, Removing, and Managing Rows\n\nThe API of `AloeStackView` generally deals with \"rows\". A row can be any `UIView` that you want to use in your UI.\n\nBy default, rows are arranged in a vertical column, and each row stretches the full width of the `AloeStackView`.\n\nThe `axis` property on `AloeStackView` can be used to change the orientation. When `axis` is set to `.horizontal`,\nrows are arranged next to each other, left-to-right, and the `AloeStackView` scrolls horizontally, with each row\nstretching the full height of the `AloeStackView`.\n\nTo build a UI with `AloeStackView`, you generally begin by adding the rows that make up your UI:\n\n```swift\nfor i in 1...3 {\n  let label = UILabel()\n  label.text = \"Label \\(i)\"\n  stackView.addRow(label)\n}\n```\n![Add rows](Docs\u002FImages\u002Fadd_rows.png)\n\nIf the length of an `AloeStackView` ever grows too long for the available screen space, the content automatically\nbecomes scrollable.\n\n![Add rows](Docs\u002FImages\u002Fadd_many_rows.gif)\n\n`AloeStackView` provides a comprehensive set of methods for managing rows, including inserting rows at the\nbeginning and end, inserting rows above or below other rows, hiding and showing rows, removing rows, and retrieving\nrows.\n\nYou can customize the spacing around a row with the `rowInset` property, and the `setInset(forRow:)` and\n`setInset(forRows:)` methods.\n\nThe class documentation in [AloeStackView.swift](Sources\u002FAloeStackView\u002FAloeStackView.swift) provides full details of\nall the APIs available.\n\n### Handling User Interaction\n\n`AloeStackView` provides support for handling tap gestures on a row:\n\n```swift\nstackView.setTapHandler(\n  forRow: label,\n  handler: { [weak self] label in\n    self?.showAlert(title: \"Row Tapped\", message: \"Tapped on: \\(label.text ?? \"\")\")\n  })\n\nlabel.isUserInteractionEnabled = true\n```\n![Add rows](Docs\u002FImages\u002Ftap_handler.gif)\n\nA tap handler will only fire if `isUserInteractionEnabled` is `true` for a row.\n\nAnother way of handling tap gestures is to conform to the `Tappable` protocol:\n\n```swift\npublic class ToggleLabel: UILabel, Tappable {\n\n  public func didTapView() {\n    textColor = textColor == .red ? .black : .red\n  }\n\n}\n\nfor i in 1...3 {\n  let label = ToggleLabel()\n  label.text = \"Label \\(i)\"\n  label.isUserInteractionEnabled = true\n  stackView.addRow(label)\n}\n```\n![Add rows](Docs\u002FImages\u002Ftappable_protocol.gif)\n\nConforming to `Tappable` allows common tap gesture handling behavior to be encapsulated inside a view. This way\nyou can reuse a view in an `AloeStackView` many times, without writing the same tap gesture handling code each\ntime.\n\n### Dynamically Changing Row Content\n\nOne of the advantages of using `AloeStackView` is that you can keep a strong reference to a view even after you've\nadded it to an `AloeStackView`.\n\nIf you change a property of a view that affects the layout of the overall UI, `AloeStackView` will automatically relayout\nall of its rows:\n\n```swift\nstackView.setTapHandler(forRow: label, handler: { label in\n  label.text = (label.text ?? \"\") + \"\\n\\nSome more text!\"\n})\n```\n![Add rows](Docs\u002FImages\u002Fdynamically_adjust_content.gif)\n\nAs you can see, there's no need to notify `AloeStackView` before or after making changes to a view. Auto Layout will\nensure that the UI remains in an up-to-date state.\n\n### Styling and Controlling Separators\n\n`AloeStackView` adds separators between rows by default:\n\n![Add rows](Docs\u002FImages\u002Fadd_rows.png)\n\n#### Turning Separators On and Off\n\nYou can easily hide separators for any rows that are added to an `AloeStackView`:\n\n```swift\nstackView.hidesSeparatorsByDefault = true\n```\n![Add rows](Docs\u002FImages\u002Fhide_separators_by_default.png)\n\nThe `hidesSeparatorsByDefault` property only applies to new rows that are added. Rows already in the\n`AloeStackView` won't be affected.\n\nYou can hide or show separators for existing rows with the `hideSeparator(forRow:)`,\n`hideSeparators(forRows:)`, `showSeparator(forRow:)`, and `showSeparators(forRows:)` methods.\n\n`AloeStackView` also provides a convenient property to automatically hide the last separator:\n\n```swift\nstackView.automaticallyHidesLastSeparator = true\n```\n![Add rows](Docs\u002FImages\u002Fhide_last_separator.png)\n\n#### Customizing Separators\n\nYou can change the spacing on the left and right of separators:\n\n```swift\nstackView.separatorInset = .zero\n```\n![Add rows](Docs\u002FImages\u002Fzero_separator_inset.png)\n\nIn vertical orientation, only the left and right properties of `separatorInset` are used.\n\nIn horizontal orientation, separators are displayed vertically between rows. In this case, only the top and bottom\nproperties of `separatorInset` are used, and they control the spacing on the top and bottom of separators.\n\nAs with `hidesSeparatorsByDefault`, the `separatorInset` property only applies to new rows that are added.\nRows already in the `AloeStackView` won't be affected.\n\nYou can change the separator inset for existing rows with the `setSeparatorInset(forRow:)` and\n`setSeparatorInset(forRows:)` methods.\n\n`AloeStackView` also provides properties for customizing the color and width (or thickness) of separators:\n\n```swift\nstackView.separatorColor = .blue\nstackView.separatorWidth = 2\n```\n![Add rows](Docs\u002FImages\u002Flarge_blue_separators.png)\n\nThese properties affect all of the separators in the `AloeStackView`.\n\n### Extending AloeStackView\n\n`AloeStackView` is an open class, so it's easy to subclass to add custom functionality without changing the original\nsource code. Additionally, `AloeStackView` provides two methods that can be used to further extend its capabilities.\n\n#### configureCell(_:)\n\nEvery row in an `AloeStackView` is wrapped in a `UIView` subclass called `StackViewCell`. This view is used for\nper-row bookkeeping and also manages UI such as separators and insets.\n\nWhenever a row is added or inserted into an `AloeStackView`, the `configureCell(_:)` method is called. This\nmethod is passed the newly created `StackViewCell` for the row.\n\nYou can override this method to perform any customization of cells as needed, for example to support custom\nfeatures you've added to `AloeStackView` or control the appearance of rows on the screen.\n\nThis method is always called after any default values for the cell have been set, so any changes you make in this\nmethod won't be overwritten by the system.\n\n#### cellForRow(_:)\n\nWhenever a row is inserted into an `AloeStackView`, the `cellForRow(_:)` method is called to obtain a new cell for\nthe row. By default, `cellForRow(_:)` simply returns a new `StackViewCell` that contains the row passed in.\n\n`StackViewCell`, however, is an open class that can be subclassed to add custom behavior and functionality as\nneeded. To have `AloeStackView` use your custom cell, override `cellForRow(_:)` and return an instance of your\ncustom subclass.\n\nProviding a custom `StackViewCell` subclass allows much more find-grained control over how rows are displayed. It\nalso allows custom data to be stored along with each row, which can be useful to support any functionality you add to\n`AloeStackView`.\n\nOne thing to remember is that `AloeStackView` will apply default values to a cell after it is returned from\n`cellForRow(_:)`. Hence, if you need to apply any further customizations to your cell, you should consider doing it in\n`configureCell(_:)`.\n\n#### When to Extend AloeStackView\n\nThese methods together provide quite a lot of flexibility for extending `AloeStackView` to add custom behavior and\nfunctionality.\n\nFor example, you can add new methods to `AloeStackView` to control the way rows are managed, or to support new\ntypes of user interaction. You can customize properties on `StackViewCell` to control the individual appearance of\neach row. You can subclass `StackViewCell` to store new data and properties with each row in order to support\ncustom features you add. Subclassing `StackViewCell` also provides more fine-grained control over how rows are\ndisplayed.\n\nHowever, this flexibility inevitably comes with a trade-off in terms of complexity and maintenance. `AloeStackView`\nhas a comprehensive API that can support a wide variety of use cases out-of-the-box. Hence, it's often better to see if\nthe behavior you need is available through an existing API before resorting to extending the class to add new features.\nThis can often save time and effort, both in terms of the cost of developing custom functionality as well as ongoing\nmaintenance.\n\n### When to use AloeStackView\n\n#### The Short Answer\n\n`AloeStackView` is best used for shorter screens with less than a screenful or two of content. It is particularly suited to\nscreens that accept user input, implement forms, or are comprised of a heterogeneous set of views.\n\nHowever, it's also helpful to dig a bit deeper into the technical details of `AloeStackView`, as this can help develop a\nbetter understanding of appropriate use cases.\n\n#### More Details\n\n`AloeStackView` is a very useful tool to have in the toolbox. Its straightforward, flexible API allows you to build UI\nquickly and easily.\n\nUnlike `UITableView` and `UICollectionView`, you can keep strong references to views in an `AloeStackView` and\nmake changes to them at any point. This will automatically update the entire UI thanks to Auto Layout - there is no\nneed to notify `AloeStackView` of the changes.\n\nThis makes `AloeStackView` great for use cases such as forms and screens that take user input. In these situations,\nit's often convenient to keep a strong reference to the fields a user is editing, and directly update the UI with validation\nfeedback.\n\n`AloeStackView` has no `reloadData` method, or any way to notify it about changes to your views. This makes it less\nerror-prone and easier to debug than a class like `UITableView`. For example, `AloeStackView` won't crash if not\nnotified of changes to the underlying data of the views it manages.\n\nSince `AloeStackView` uses `UIStackView` under the hood, it doesn't recycle views as you scroll. This eliminates\ncommon bugs caused by not recycling views correctly. You also don't need to independently maintain the state of\nviews as the user interacts with them, which makes it simpler to implement certain kinds of UI.\n\nHowever, `AloeStackView` is not suitable in all situations. `AloeStackView` lays out the entire UI in a single pass\nwhen your screen loads. As such, longer screens will start seeing a noticeable delay before the UI is displayed for the\nfirst time. This is not a great experience for users and can make an app feel unresponsive to navigation actions.\nHence, `AloeStackView` should not be used when implementing UI with more than a screenful or two of content.\n\nForgoing view recycling is also a trade-off: while `AloeStackView`  is faster to write UI with and less error-prone, it will\nperform worse and use more memory for longer screens than a class like `UITableView`. Hence, `AloeStackView` is\ngenerally not appropriate for screens that contain many views of the same type, all showing similar data. Classes like\n`UITableView` or `UICollectionView` often perform better in those situations.\n\n## Installation\n\n`AloeStackView` can be installed with [Carthage](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage). Simply add\n`github \"marlimox\u002FAloeStackView\"` to your Cartfile.\n\n`AloeStackView` can be installed with [CocoaPods](http:\u002F\u002Fcocoapods.org). Simply add\n`pod 'AloeStackView'` to your Podfile.\n\n## Contributions\n\n`AloeStackView` is feature complete for the use cases it was originally designed to address. However, UI\ndevelopment on iOS is never a solved problem, and we expect new use cases to arise and old bugs to be uncovered.\n\nAs such we fully welcome contributions, including new features, feature requests, bug reports, and fixes. If you'd like\nto contribute, simply push a PR with a description of your changes. You can also file a GitHub Issue for any bug\nreports or feature requests.\n\nPlease feel free to email the project maintainers if you'd like to get in touch. We'd love to hear from you if you or your\ncompany has found this library useful!\n\n## Maintainers\n\n`AloeStackView` is developed and maintained by:\n\n[Marli Oshlack](https:\u002F\u002Fgithub.com\u002Fmarlimox) (marli@oshlack.com)\n\n[Arthur Pang](https:\u002F\u002Fgithub.com\u002Fapang42)\n\n## Contributors\n\n`AloeStackView` has benefited from the contributions of many other engineers:\n\nDaniel Crampton, Francisco Diaz, David He, Jeff Hodnett, Eric Horacek, Garrett Larson, Jasmine Lee, Isaac Lim,\nJacky Lu, Noah Martin, Phil Nachum, Gonzalo Nuñez, Laura Skelton, Cal Stephens, and Ortal Yahdav\n\nIn addition, open sourcing this project wouldn't have been possible without the help and support of Jordan Harband,\nTyler Hedrick, Michael Bachand, Laura Skelton, Dan Federman, and John Pottebaum.\n\n## License\n\n`AloeStackView` is released under the Apache License 2.0. See LICENSE for details.\n\n## Why is it called AloeStackView?\n\nWe like succulents and find the name soothing 😉\n","AloeStackView 是一个用于布局视图集合的简单类，通过便捷的API利用Auto Layout的强大功能。其核心功能包括动态添加、移除、隐藏和显示视图，并支持自定义分隔线样式与动画效果。AloeStackView 旨在简化UI实现过程，提供直观且易于使用的接口，同时保持对视图属性变更的即时响应。该项目特别适用于需要快速构建简洁用户界面的iOS应用开发场景中，尤其当开发者希望避免复杂的表格视图逻辑时。代码库小巧（少于600行），易于理解和维护，无外部依赖，确保了较低的学习曲线与高效的开发体验。",2,"2026-06-11 03:10:21","top_language"]