{"id":19847028,"url":"https://github.com/polidea/plxframelayout","last_synced_at":"2025-07-21T10:05:22.555Z","repository":{"id":56921283,"uuid":"43116760","full_name":"Polidea/PLXFrameLayout","owner":"Polidea","description":"AutoLayout on frames","archived":false,"fork":false,"pushed_at":"2016-02-01T15:39:11.000Z","size":73,"stargazers_count":3,"open_issues_count":3,"forks_count":1,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-07-08T02:17:53.538Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Objective-C","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/Polidea.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":"2015-09-25T07:39:48.000Z","updated_at":"2016-03-13T17:03:21.000Z","dependencies_parsed_at":"2022-08-21T04:50:42.778Z","dependency_job_id":null,"html_url":"https://github.com/Polidea/PLXFrameLayout","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Polidea/PLXFrameLayout","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polidea%2FPLXFrameLayout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polidea%2FPLXFrameLayout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polidea%2FPLXFrameLayout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polidea%2FPLXFrameLayout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Polidea","download_url":"https://codeload.github.com/Polidea/PLXFrameLayout/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Polidea%2FPLXFrameLayout/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266278376,"owners_count":23904041,"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":[],"created_at":"2024-11-12T13:13:15.351Z","updated_at":"2025-07-21T10:05:22.539Z","avatar_url":"https://github.com/Polidea.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PLXFrameLayout\n\n###Desciption\n**PLXFrameLayout** is a small frame for positioning, sizing and arranging views without using CGRects. **PLXFrameLayout** also provides set of convinient read-write properties that extract/set discrete values from view's frame, like: width, height, minX/Y, maxX/Y.\n\nIt's _not_ Autolayout support. You can use it with Autolayout if needed.\n\n###How it works\n**PLXFrameLayout** is defined as a category on `UIView` class. It contains set of methods to configure view's sizes and positions in relation to its superviews or other views. Under the hood all **PLXFrameLayout** methods calculates and sets `view.frame` property.\n\n###How to use\n\nLet's consider following typical layout on frames.\n\n```objective-c\n- (void)layoutSubviews {\n\t[super layoutSubviews];\n\t\n\t[self.titleLabel sizeToFit];\n\tCGRect titleLabelFrame = self.titleLabel.frame;\n\ttitleLabelFrame.origin.x = CGRectGetMidX(self.bounds) - (CGRectGetWidth(titleLabelFrame) * 0.5f);\n\ttitleLabelFrame.origin.y = CGRectGetMidY(self.bounds) - (CGRectGetHeight(titleLabelFrame) * 0.5f);\n\tself.titleLabel.frame = titleLabelFrame;\n\t\n\t[self.captionLabel sizeToFit];\n\tCGRect captionLabelFrame = self.captionLabel.frame;\n\tcaptionLabelFrame.origin.y = CGRectGetMaxY(self.titleLabel.frame) + 10.f;\n\tcaptionLabelFrame.origin.x = CGRectGetMinX(self.titleLabel.frame);\n\tself.captionLabel.frame = captionLabelFrame;\n\t\n\tCGRect otherViewFrame = self.otherView.frame;\n\totherViewFrame.origin.x = CGRectGetMaxX(self.titleLabel.frame) + 10.f;\n\totherViewFrame.origin.y = CGRectGetMidY(self.titleLabel.frame) - (CGRectGetHeight(otherViewFrame) * 0.5f);\n\totherViewFrame.size.width = CGRectGetWidth(self.bounds) - CGRectGetMinX(otherViewFrame) - 10.f;\n\tself.otherView.frame = otherViewFrame;\n}\n```\n\nNow, let's look at implementation using `PLXFrameLayout`.\n\n```objective-c\n- (void)layoutSubviews {\n\t[super layoutSubviews];\n\t[self plx_sizeToFitSubviews];\n\t\n\t[self.titleLabel plx_centerInSuperView];\n\t[self.captionLabel plx_placeUnderAligningToLeft:self.titleLabel withMargin:10.f];\n\t[self.otherView plx_placeOnRightOf:self.titleLabel withMargin:10.f];\n\t[self.otherView plx_expandToSuperViewEdge:NSLayoutAttributeRight withInset:10.f];\n\t[self.otherView plx_alignToAttribute:NSLayoutAttributeCenterY ofView:self.titleLabel offset:0];\n}\n```\n\nIt's one way of how it could be done with `PLXFrameLayout`. It looks much better and more legible than usual code with lots of `CGRect` functions and structs copies.\n\nIn first line we center the view in superview with one method call. Then we place `captionLabel` under `titleLabel` and align its `x` to the same property value of `titleView` - all with one method.\n`otherView` is placed on right of `titleLabel`, then its width is expanded so `maxX` is equal to super view `maxX` minus inset (`10.f`), and finally it's centered relatively to `titleLabel` center `y`.\n\n###Installation\n\n#####Pods installation\n\n1. Add the pod **PLXFrameLayout** to your Podfile:\n\n\t```\n\tpod 'PLXFrameLayout'\n\t```\n\t\n2. Run `pod install` from Terminal, then open your app's .xcworkspace file to launch your IDE.\n\n3. Import the header file:\n \n\t```objective-c\n\t#import \"UIView+PLXFrameLayout.h\"\n\t```\n\n#####Manual instalation\n1. Drag and drop `UIView+PLXFrameLayout.h` and `UIView+PLXFrameLayout.m`  to your project;\n2. In *File Inspector*, make sure that `UIView+PLXFrameLayout.m` belongs to your app target;\n3. Add `#import UIView+PLXFrameLayout.h` to your file.\n\n###Detailed usage\n\n####Assignable properties\n\nThere are a few most common properties that you may want to change to achieve desired layout of the view.\n\n```objective-c\n@property(nonatomic, assign, setter=pl_setMinY:) CGFloat plx_minY;\n@property(nonatomic, assign, setter=pl_setMidY:) CGFloat plx_midY;\n@property(nonatomic, assign, setter=pl_setMaxY:) CGFloat plx_maxY;\n@property(nonatomic, assign, setter=pl_setMinX:) CGFloat plx_minX;\n@property(nonatomic, assign, setter=pl_setMidX:) CGFloat plx_midX;\n@property(nonatomic, assign, setter=pl_setMaxX:) CGFloat plx_maxX;\n@property(nonatomic, assign, setter=pl_setWidth:) CGFloat plx_width;\n@property(nonatomic, assign, setter=pl_setHeight:) CGFloat plx_height;\n@property(nonatomic, assign, setter=pl_setSize:) CGSize plx_size;\n@property(nonatomic, assign, setter=pl_setFrame:) CGRect plx_frame;\n```\n\nEach property is assignable. That means that it's no longer necessary to make a copy of `CGRect` change it and assign back. E.g. modifiyng `plx_midX` changes the `x` value of view's frame considering its width, so it can be treated as center x of that view.\n\n####Centering\n\nThere are a few methods that allow easily center the view relatively to its superview or sibling.\n\n```objective-c\n- (void)plx_centerInSuperView;\n- (void)plx_centerXInSuperView;\n- (void)plx_centerYInSuperView;\n\n- (void)plx_alignToCenterOfView:(UIView *)view;\n- (void)plx_alignToCenterXOfView:(UIView *)view;\n- (void)plx_alignToCenterYOfView:(UIView *)view;\n```\n\n####Alignment\n\nThere are lots of methods that make views' alignment easy.\n\n#####Core\n\nThe most fundamental method allows to align any attributes of two given views. Howerver not all attributes' combinations make sense or are supported.\n\n```objective-c\n- (void)plx_alignAttribute:(NSLayoutAttribute)attribute toAttribute:(NSLayoutAttribute)outerAttribute ofView:(UIView *)view;\n- (void)plx_alignAttribute:(NSLayoutAttribute)attribute toAttribute:(NSLayoutAttribute)outerAttribute ofView:(UIView *)view offset:(CGFloat)offset;\n- (void)plx_alignAttribute:(NSLayoutAttribute)attribute toAttribute:(NSLayoutAttribute)outerAttribute ofView:(UIView *)view multiplier:(CGFloat)multiplier;\n- (void)plx_alignAttribute:(NSLayoutAttribute)attribute toAttribute:(NSLayoutAttribute)outerAttribute ofView:(UIView *)view multiplier:(CGFloat)multiplier offset:(CGFloat)offset;\n``` \n\nLast method is the basic one, all others are just syntactic sugar. It look similarly to its Autolayout equivalent and behaves similarly as well.\n\nIf you want to align the same attributes of both views you may use additional method:\n\n```objective-c\n- (void)plx_alignToAttribute:(NSLayoutAttribute)edgeAttribute ofView:(UIView *)view withOffset:(CGFloat)offset;\n```\n\nFinally, there's one method that allows to align given attribute of the view to the same attribute of its superview:\n\n```objective-c\n- (void)plx_alignToSuperViewAttribute:(NSLayoutAttribute)edgeAttribute withOffset:(CGFloat)offset;\n```\n\n#####Handy helpers\n\nFollowing methods are easy to use and understand. They help to position view relatively to the given view: under/above/on the left/right. Two of them have additional variations with extra alignment in X axis.\n\nNote: `margin` has always positive value (in opposite to `offset` parameter above). E.g. using `plx_placeOnLeftOf:withMargin:` positive `margin` value will move view more to the left (_not_ to the right, in the X axis direction).\n\n```objective-c \n- (void)plx_placeUnder:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeAbove:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeOnLeftOf:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeOnRightOf:(UIView *)view withMargin:(CGFloat)margin;\n\n- (void)plx_placeAboveAligningCenterX:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeAboveAligningToLeft:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeAboveAligningToRight:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeUnderAligningCenterX:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeUnderAligningToLeft:(UIView *)view withMargin:(CGFloat)margin;\n- (void)plx_placeUnderAligningToRight:(UIView *)view withMargin:(CGFloat)margin;\n```\n\n#####Batch alignment\n\nThere are two core methods `plx_alignViewsVertically`: and `plx_alignViewsHorizontally:` with their variations to allow batch views alignment. They accept an array of views _and_ numbers (as spacec between those views).\n\nNote: Each method retuns total calculated height of all aligned views with spaces.\n\n```objective-c\n- (CGFloat)plx_alignViewsVertically:(NSArray *)viewsAndSpacings;\n- (CGFloat)plx_alignViewsVerticallyCentering:(NSArray *)viewsAndSpacings;\n- (CGFloat)plx_alignViewsVertically:(NSArray *)viewsAndSpacings centeringWithMargin:(CGFloat)spaceFromCenter;\n- (CGFloat)plx_alignViewsVertically:(NSArray *)viewsAndSpacings additionallyAligningTo:(NSLayoutAttribute)attribute withMargin:(CGFloat)marginFromAttribute;\n\n- (CGFloat)plx_alignViewsHorizontally:(NSArray *)viewsAndSpacings;\n- (CGFloat)plx_alignViewsHorizontallyCentering:(NSArray *)viewsAndSpacings;\n- (CGFloat)plx_alignViewsHorizontally:(NSArray *)viewsAndSpacings centeringWithMargin:(CGFloat)spaceFromCenter;\n- (CGFloat)plx_alignViewsHorizontally:(NSArray *)viewsAndSpacings additionallyAligningTo:(NSLayoutAttribute)attribute withMargin:(CGFloat)marginFromAttribute;\n```\n\nHere is an example.\n\n```objective-c\n[self plx_alignViewsVertically:@[\n\tself.titleLabel,\n\t@20,\n\tself.captionLabel,\n]];\n```\n\nThis code means that `titleLabel` will be aligned to the superview's top, then under it after `20` points `captionLabel` will be places. In this example `x` property value will not be modified.\n\n####Expand\n\nThere are methods that help to expand views as well (not only align their edges).\n\n```objective-c\n- (void)plx_expandToSuperViewEdges;\n- (void)plx_expandToSuperViewEdgesWithInsets:(UIEdgeInsets)insets;\n \n- (void)plx_expandToSuperViewHorizontalEdgesWithInsets:(UIEdgeInsets)insets;\n- (void)plx_expandToSuperViewVerticalEdgesWithInsets:(UIEdgeInsets)insets;\n\n- (void)plx_expandToSuperViewEdge:(NSLayoutAttribute)edge withInset:(CGFloat)inset;\n```\n\nFirst two methods resize the view to the superview bounds. It similar to the: `self.titleLabel.frame = self.bounds;`, however you may pass insets if necessary.\n\nNext two methods allow to expand view the only in desired axis: horizontal (X) or vertical (Y). That means e.g. if `self.titleLabel` should fill all the width of superview (from 0 to superview's bounds maxX) but not changing `y` and `height` properties - `plx_expandToSuperViewVerticalEdgesWithInsets:` should be used.\n\nLast method allows to expand only one edge to the same edge of superview identified by `NSLayoutAttributeTop/Bottom/Left/Right`.\n\n####Fill\n\nSometimes there are views that don't have intrinsic content size (e.g. scroll view) and their height (or width) has to be dynamically calculated and set. In this cases two following method may help.\n\n```objective-c\n- (void)plx_fillSuperViewVertically:(NSArray *)viewsAndSpacings expandableViews:(NSArray *)expandableViews;\n- (void)plx_fillSuperViewHorizontally:(NSArray *)viewsAndSpacing expandableViews:(NSArray *)expandableViews;\n```\n\nThey work similarly to the `plx_alignViewsVertically/Horizontally:` methods, but take one more paramter.\nThis is an array of views (that should be listed as well in first array parameter) that are allowed be expanded (not only aligned).\n\nHere is an example.\n\n```objective-c\n[self plx_fillSuperViewVertically:@[\n\tself.titleLabel,\n\tself.tableView,\n\tself.footerLabel,\n] expandableViews:@[self.tableView]];\n```\n\nIt means that views will be aligned in vertical axis but table view will be additional expanded to fill all available superview space (height).\n\n####Distribute\n\nSometimes there's a need to equally distribute views in superview (with equal margins between them).\nFollowing methods are able to do that.\n\n```objective-c\n- (void)plx_distributeSubviewsVerticallyInSuperView:(NSArray *)subviews withTopAndBottomMargin:(BOOL)shouldAddTopAndBottomMargins;\n- (void)plx_distributeSubviewsHorizontallyInSuperView:(NSArray *)subviews withLeftAndRightMargin:(BOOL)shouldAddLeftAndRightMargin;\n```\n\nNote: The second parameter of each method determines whether the margin between super view edges and first and last views should be consider in computation.\n\n###Contribution\n\nFeel free to contribute by pull requests or create issues.\n\n###License\n**PLXFrameLayout** is released under a MIT License. See LICENSE file for details.\n\n## Author\nMaciej Oczko (maciek.oczko@polidea.com), Paweł Ścibek (pawel.scibek@polidea.com)\n\n[Polidea](http://www.polidea.com/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolidea%2Fplxframelayout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolidea%2Fplxframelayout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolidea%2Fplxframelayout/lists"}