Coder Social home page Coder Social logo

youngsoft / tangramkit Goto Github PK

View Code? Open in Web Editor NEW
1.2K 49.0 175.0 5.61 MB

TangramKit is a powerful iOS UI framework implemented by Swift. It integrates the functions with Android layout,iOS AutoLayout,SizeClass, HTML CSS float and flexbox and bootstrap. So you can use LinearLayout,RelativeLayout,FrameLayout,TableLayout,FlowLayout,FloatLayout,LayoutSizeClass to build your App 自动布局 UIView UITableView UICollectionView

License: MIT License

Ruby 0.38% Swift 99.58% Objective-C 0.04%
autolayout android swift ios constraints uitableview uicollectionview xcode ui view

tangramkit's Introduction

Version License Platform Carthage compatible Support Weibo QQ GitHub stars

logo

TangramKit logo

TangramKit is a simple and easy Swift framework for iOS view layout. The name comes from Tangram of China which provides some simple functions to build a variety of complex interface. It integrates the functions including: Autolayout and SizeClass of iOS, five layout classes of Android, float and flex-box and bootstrap of HTML/CSS. The TangramKit's objective-C version are named: MyLayout

cn Chinese (Simplified): 中文说明

Usage

  • There is a container view S which width is 100 and height is wrap to all subviews height. there are four subviews A,B,C,D arranged from top to bottom.
  • Subview A's left margin is 20% width of S, right margin is 30% width of S, height is equal to width of A.
  • Subview B's left margin is 40, width is filled in to residual width of S,height is 40.
  • Subview C's width is filled in to S, height is 40.
  • Subview D's right margin is 20, width is 50% width of S, height is 40

demo

    let S = TGLinearLayout(.vert)
    S.tg_vspace = 10
    S.tg_width.equal(100)
    S.tg_height.equal(.wrap)
    //you can use S.tg_size(width:100, height:.wrap) to instead
    
    let A = UIView()
    A.tg_left.equal(20%)
    A.tg_right.equal(30%)
    A.tg_height.equal(A.tg_width)
    S.addSubview(A)
    
    let B = UIView()
    B.tg_left.equal(40)
    B.tg_width.equal(.fill)
    B.tg_height.equal(40)
    S.addSubview(B)
    
    let C = UIView()
    C.tg_width.equal(.fill)
    C.tg_height.equal(40)
    S.addSubview(C)
    
    let D = UIView()
    D.tg_right.equal(20)
    D.tg_width.equal(50%)
    D.tg_height.equal(40)
    S.addSubview(D)
    

TangramKit has override operators: ~=、>=、<=、+=、-=、*=、/= to implement equal、max、min、add、offset、multiply methods of TGLayoutSize and TGLayoutPos class, so you can instead to:

let S = TGLinearLayout(.vert)
   S.tg_vspace = 10
   S.tg_width ~=100
   S.tg_height ~=.wrap
   
   let A = UIView()
   A.tg_left ~=20%
   A.tg_right ~=30%
   A.tg_height ~=A.tg_width
   S.addSubview(A)
   
   let B = UIView()
   B.tg_left ~=40
   B.tg_width ~=.fill
   B.tg_height ~=40
   S.addSubview(B)
   
   let C = UIView()
   C.tg_width ~=.fill
   C.tg_height ~=40
   S.addSubview(C)
   
   let D = UIView()
   D.tg_right ~=20
   D.tg_width ~=50%
   D.tg_height ~=40
   S.addSubview(D)

Performance comparison

demo

create time(ms)/per subview Frame TangramKit AutoLayout Masonry UIStackView
TGLinearLayout 0.08 0.164 0.219 0.304 0.131
TGFrameLayout 0.05 0.149 0.209 0.273 0.131
TGRelativeLayout 0.079 0.182 0.116 0.359 0.131
TGFlowLayout 0.08 0.107 0.198 0.258 0.131
TGFloatLayout 0.044 0.148 0.203 0.250 0.131
layout time(ms)/per subview Frame TangramKit AutoLayout Masonry UIStackView
TGLinearLayout 0 0.049 0.269 0.269 0.272
TGFrameLayout 0 0.042 0.243 0.243 0.272
TGRelativeLayout 0 0.068 0.274 0.274 0.272
TGFlowLayout 0 0.036 0.279 0.279 0.272
TGFloatLayout 0 0.055 0.208 0.208 0.272

Architecture

demo

TGLayoutPos

TGLayoutPos is represent to the position of a view. UIView provides six extension variables:tg_left, tg_top, tg_bottom, tg_right, tg_centerX, tg_centerY to set view's margin or space distance between self and others.

TGLayoutSize

TGLayoutSize is represent to the size of a view. UIView provides two extension variables:tg_width,tg_height to set view's width and height dimension. there are three special TGLayoutSize const object: .wrap, .fill, .average mean: wrap all subviews size, fill in to superview's residual size, average the superview's size.

TGWeight

TGWeight is used to set relative position and dimension. TangramKit override operator % to easily construct a TGWeight object. e.g 20% is equal to TGWeight(20).

TGLinearLayout

Is equivalent to: UIStackView of iOS and LinearLayout of Android.

Linear layout is a single line layout view that the subviews are arranged in sequence according to the added order(from top to bottom or from left to right). So the subviews' origin&size constraints are established by the added order. Subviews arranged in top-to-bottom order is called vertical linear layout view, and the subviews arranged in left-to-right order is called horizontal linear layout.

演示效果图

override func loadView() {
        
        
            super.loadView()
        
            let S = TGLinearLayout(.vert)
            S.tg_width.equal(120)
            S.tg_height.equal(.wrap)
            S.tg_vspace = 10
            
            let A = UIView()
            A.tg_left.equal(5)
            A.tg_right.equal(5)
            A.tg_width.equal(100)
            A.tg_height.equal(40)
            S.addSubview(A)
            
            let B = UIView()
            B.tg_left.equal(20)
            B.tg_width.equal(40)
            B.tg_height.equal(40)
            S.addSubview(B)
            
            let C = UIView()
            C.tg_right.equal(40)
            C.tg_width.equal(50)
            C.tg_height.equal(40)
            S.addSubview(C)
            
            let D = UIView()
            D.tg_left.equal(10)
            D.tg_right.equal(10)
            D.tg_width.equal(100)
            D.tg_height.equal(40)
            S.addSubview(D)
            
            self.view.addSubview(S)
            S.backgroundColor = .red
            A.backgroundColor = .green
            B.backgroundColor = .blue
            C.backgroundColor = .orange
            D.backgroundColor = .cyan
     }

TGRelativeLayout

Is equivalent to: AutoLayout of iOS and RelativeLayout of Android.

Relative layout is a layout view that the subviews layout and position through mutual constraints.The subviews in the relative layout are not depended to the adding order but layout and position by setting the subviews' constraints.

演示效果图

override func loadView() {
        
        
            super.loadView()
        
        let S = TGRelativeLayout()
        S.tg_width.equal(170).and().tg_height.equal(280)
        
        let A = UIView()
        A.tg_left.equal(20).and().tg_top.equal(20)
        A.tg_width.equal(40).and().tg_height.equal(A.tg_width)
        S.addSubview(A)
        
        let B = UIView()
        B.tg_left.equal(A.tg_centerX).and().tg_top.equal(A.tg_bottom).offset(10)
        B.tg_width.equal(60).and().tg_height.equal(A.tg_height)
        S.addSubview(B)
        
        let C = UIView()
        C.tg_left.equal(B.tg_right).offset(10)
        C.tg_bottom.equal(B.tg_bottom)
        C.tg_width.equal(40)
        C.tg_height.equal(B.tg_height, multiple:0.5)
        S.addSubview(C)
        
        let D = UIView()
        D.tg_bottom.equal(C.tg_top).offset(10)
        D.tg_right.equal(15)
        D.tg_height.equal(A.tg_height)
        D.tg_width.equal(D.tg_height)
        S.addSubview(D)
        
        let E = UIView()
        E.tg_centerY.equal(0)
        E.tg_centerX.equal(0)
        E.tg_height.equal(40)
        E.tg_width.equal(S.tg_width).add(-20)
        S.addSubview(E)
        //...F,G
        
            self.view.addSubview(S)
            S.backgroundColor = .red
            A.backgroundColor = .green
            B.backgroundColor = .blue
            C.backgroundColor = .orange
            D.backgroundColor = .cyan
            E.backgroundColor = .magenta
       }

TGFrameLayout

Is equivalent to: FrameLayout of Android.

Frame layout is a layout view that the subviews can be overlapped and gravity in a special location of the superview.The subviews' layout position&size is not depended to the adding order and establish dependency constraint with the superview. Frame layout devided the vertical orientation to top,vertical center and bottom, while horizontal orientation is devided to left,horizontal center and right. Any of the subviews is just gravity in either vertical orientation or horizontal orientation.

演示效果图

 override func loadView() {
        
        
        super.loadView()
        
        let S = TGFrameLayout()
        S.tg_width.equal(320)
        S.tg_height.equal(500)
        
        let A = UIView()
        A.tg_width.equal(40)
        A.tg_height.equal(40)
        S.addSubview(A)
        
        let B = UIView()
        B.tg_width.equal(40)
        B.tg_height.equal(40)
        B.tg_right.equal(0)
        S.addSubview(B)
        
        let C = UIView()
        C.tg_width.equal(40)
        C.tg_height.equal(40)
        C.tg_centerY.equal(0)
        S.addSubview(C)
        
        let D = UIView()
        D.tg_width.equal(40)
        D.tg_height.equal(40)
        D.tg_centerY.equal(0)
        D.tg_centerX.equal(0)
        S.addSubview(D)
        
        //..E,F,G
        
        self.view.addSubview(S)
        S.backgroundColor = .red
        A.backgroundColor = .green
        B.backgroundColor = .blue
        C.backgroundColor = .orange
        D.backgroundColor = .cyan
}
  

TGTableLayout

Is equivalent to: TableLayout of Android and table of HTML.

Table layout is a layout view that the subviews are multi-row&col arranged like a table. First you must create a rowview and add it to the table layout, then add the subview to the rowview. If the rowviews arranged in top-to-bottom order,the tableview is caled vertical table layout,in which the subviews are arranged from left to right; If the rowviews arranged in in left-to-right order,the tableview is caled horizontal table layout,in which the subviews are arranged from top to bottom.

演示效果图

   override func loadView() {
        
        
        super.loadView()
        
        let S = TGTableLayout(.vert)
        S.tg_height.equal(.wrap)
        S.tg_width.equal(.wrap)
        S.tg_vspace = 10
        S.tg_hspace = 10
        
        
        S.tg_addRow(size:TGLayoutSize.wrap,colSize:TGLayoutSize.wrap)
        
        let A = UIView()
        A.tg_width.equal(50)
        A.tg_height.equal(40)
        S.addSubview(A)
        
        let B = UIView()
        B.tg_width.equal(100)
        B.tg_height.equal(40)
        S.addSubview(B)
        
        let C = UIView()
        C.tg_width.equal(30)
        C.tg_height.equal(40)
        S.addSubview(C)
        
        S.tg_addRow(size:TGLayoutSize.wrap,colSize:TGLayoutSize.wrap)
        
        let D = UIView()
        D.tg_width.equal(200)
        D.tg_height.equal(40)
        S.addSubview(D)
        
        //...E,F  
        
        self.view.addSubview(S)
        S.backgroundColor = .red
        A.backgroundColor = .green
        B.backgroundColor = .blue
        C.backgroundColor = .orange
        D.backgroundColor = .cyan       
}  
  
  

TGFlowLayout

Is equivalent to: flexbox of CSS3.

Flow layout is a layout view presents in multi-line that the subviews are arranged in sequence according to the added order, and when meeting with a arranging constraint it will start a new line and rearrange. The constrains mentioned here includes count constraints and size constraints. The orientation of the new line would be vertical and horizontal, so the flow layout is divided into: count constraints vertical flow layout, size constraints vertical flow layout, count constraints horizontal flow layout, size constraints horizontal flow layout. Flow layout often used in the scenes that the subviews is arranged regularly, it can be substitutive of UICollectionView to some extent. the TGFlowLayout is almost implement the flex-box function of the HTML/CSS.

演示效果图

   override func loadView() {
        
        
        super.loadView()
        
        let S = TGFlowLayout(.vert,arrangedCount:4)
        S.tg_height.equal(.wrap)
        S.tg_width.equal(300)
        S.tg_padding = UIEdgeInsetsMake(10,10,10,10)
        S.tg_gravity = TGGravity.horz.fill
        S.tg_space = 10
        
        for _ in 0 ..< 10
        {
            let A = UIView()
            A.tg_height.equal(A.tg_width)
            S.addSubview(A)
            
            A.backgroundColor = .green
        }
        
        self.view.addSubview(S)
        S.backgroundColor = .red
}   
   

TGFloatLayout

Is equivalent to: float of CSS.

Float layout is a layout view that the subviews are floating gravity in the given orientations, when the size is not enough to be hold, it will automatically find the best location to gravity. float layout's conception is reference from the HTML/CSS's floating positioning technology, so the float layout can be designed in implementing irregular layout. According to the different orientation of the floating, float layout can be divided into left-right float layout and up-down float layout.

演示效果图

     override func loadView() {
        
        
        super.loadView()
        
        let S = TGFloatLayout(.vert)
        S.tg_height.equal(.wrap)
        S.tg_width.equal(300)
        S.tg_padding = UIEdgeInsetsMake(10,10,10,10)
        S.tg_space = 10
        
        let A = UIView()
        A.tg_width.equal(80)
        A.tg_height.equal(70)
        S.addSubview(A)
        
        let B = UIView()
        B.tg_width.equal(150)
        B.tg_height.equal(40)
        S.addSubview(B)
        
        let C = UIView()
        C.tg_width.equal(70)
        C.tg_height.equal(40)
        S.addSubview(C)
        
        let D = UIView()
        D.tg_width.equal(100)
        D.tg_height.equal(140)
        S.addSubview(D)
        
        let E = UIView()
        E.tg_width.equal(150)
        E.tg_height.equal(40)
        E.tg_reverseFloat = true
        S.addSubview(E)
        
        let F = UIView()
        F.tg_width.equal(120)
        F.tg_height.equal(60)
        S.addSubview(F)
      
        self.view.addSubview(S)
        S.backgroundColor = .red
        A.backgroundColor = .green
        B.backgroundColor = .blue
        C.backgroundColor = .orange
        D.backgroundColor = .black
        E.backgroundColor = .magenta
        F.backgroundColor = .white
}     

TGPathLayout

Is unique characteristic layout view of iOS.

Path layout is a layout view that the subviews are according to a specified path curve to layout. You must provide a type of Functional equation,a coordinate and a type of distance setting to create a Path Curve than all subview are equidistance layout in the Path layout. path layout usually used to create some irregular and gorgeous UI layout.

演示效果图

Sample code:

override func loadView() 
{
       
   super.loadView()
   
   let S = TGPathLayout()
   S.tg_width.equal(320)
   S.tg_height.equal(320)
   S.tg_coordinateSetting.isReverse = true
   S.tg_coordinateSetting.origin = CGPoint(x: 0.5, y: 0.2) 
   S.tg_polarEquation = { 80 * (1 + cos(CGFloat($0))) } // r = a *(1 + cos(𝛉))
   
   for _ in 0 ..< 4
   {
       let A = UIView()
       A.tg_size(width:40,height:40)
       S.addSubview(A)
       
       A.backgroundColor = .green
   }

   self.view.addSubview(S)
   S.backgroundColor = .red
}

TGViewSizeClass

Is equivalent to: Size Classes of iOS.

TangramKit provided support to SizeClass in order to fit the different screen sizes of devices. You can combinate the SizeClass with any of the 6 kinds of layout views mentioned above to perfect fit the UI of all equipments.

    public func tg_fetchSizeClass(with type:TGSizeClassType, from srcType:TGSizeClassType! = nil) ->TGViewSizeClass
//all device
let rootLayout = TGLinearLayout(.vert)
        rootLayout.tg_padding = UIEdgeInsetsMake(10, 10, 10, 10);
        rootLayout.tg_vspace = 10
        rootLayout.tg_hspace = 10
        
//iPhone landscape orientation.
let lsc = rootLayout.tg_fetchSizeClass(with: .comb(.any, .compact, nil), from:.default) as! TGLinearLayoutViewSizeClass
        lsc.tg_orientation = .horz

Demo sample

演示效果图 演示效果图 演示效果图 演示效果图 演示效果图 演示效果图 演示效果图

How To Get Started

Download TangramKit

Communication

  • If you need help, use Stack Overflow or Baidu. (Tag 'TangramKit')
  • If you'd like to contact me, use qq:156355113 or weibo:欧阳大哥 or email:[email protected]
  • If you found a bug, and can provide steps to reliably reproduce it, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

Installation

TangramKit supports multiple methods for installing the library in a project.

Copy to your project

  1. Copy TangramKit folder from the demo project to your project

Installation with CocoaPods

CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like TangramKit in your projects. You can install it with the following command:

$ gem install cocoapods

To integrate TangramKit into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

pod 'TangramKit'

Then, run the following command:

$ pod install

  1. Create a Cartfile file.

    github "youngsoft/TangramKit"
    
  2. Run carthage update.

  3. On your application targets’ “General” settings tab, in the “Linked Frameworks and Libraries” section, drag and drop TangramKit framework from the Carthage/Build folder on disk.

  4. On your application targets’ “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”. Create a Run Script in which you specify your shell (ex: bin/sh), add the following contents to the script area below the shell:

    /usr/local/bin/carthage copy-frameworks
    

    and add the path under “Input Files”, e.g.:

    $(SRCROOT)/Carthage/Build/iOS/TangramKit.framework
    

FAQ

  • If you use TangramKit runtime cause 100% CPU usage said appeared constraint conflict, please check the subview's constraint set.

License

TangramKit is released under the MIT license. See LICENSE for details.

Thanks to the partners:

闫涛: Github homepage 张光凯: Github homepage 周杰: Github 阳光不锈:Github Hanwp: Github Blog X: Github

Version History

CHANGELOG.md

tangramkit's People

Contributors

ccat00 avatar eric0625 avatar youngsoft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tangramkit's Issues

tg_setSubviews失效

  请教个问题,把下面的代码运行一下,会发现vertLayout.tg_setSubviews(size:60, minSpace:10, maxSpace:CGFloat.greatestFiniteMagnitude)无效,

但是把下面的代码放入官方提供的Demo中,就有效!
我想知道是哪里的原因?

    let vertLayout = TGFlowLayout(.vert, arrangedCount: 4)
    //这个垂直流式布局中,每个子视图之间的水平间距是浮动的,并且子视图的宽度是固定为60。间距最小为10,最大不限制。
    vertLayout.tg_setSubviews(size:60, minSpace:10, maxSpace:CGFloat.greatestFiniteMagnitude)
    vertLayout.tg_padding = UIEdgeInsets.init(top: 5, left: 5, bottom: 5, right: 5)
    vertLayout.backgroundColor = .lightGray
    vertLayout.tg_vspace = 20
    vertLayout.tg_size(width: .fill, height: .fill)
    vertLayout.tg_gravity = TGGravity.fill
    //因为上面tg_setSubviews设置了固定宽度,这个属性设置子视图的高度是填充满子布局视图,因此系统内部会自动设置每个子视图的高度,如果你不设置这个属性,那么你就需要在下面分别为每个子视图设置高度。
    self.view.addSubview(vertLayout)
    
    for i in 0 ..< 14
    {
        let label = UILabel()
        //label.tg_height.equal(60)  因为子视图的宽度在布局视图的tg_setSubviews中设置了,你也可以在这里单独为每个子视图设置高度,当然如果你的父布局视图使用了tg_gravity来设置填充属性的话,那么子视图是不需要单独设置高度尺寸的。
        label.text = "\(i)" //[NSString stringWithFormat:@"%d", i];
        label.textAlignment = .center
        label.backgroundColor = .red
        vertLayout.addSubview(label)
    }

【BUG】非布局视图layoutSubviews相关

BUG 报告

swift和OC同时存在。

环境 版本
Xcode Version 11.2.1 (11B53)
Swift 5.0
设备信息 IPhoneX
设备版本 13.2.2

重现步骤:

  1. 修改Demo为TabbarController 嵌套UINavigationController

    代码如下:

    self.window =  UIWindow(frame: UIScreen.main.bounds)
            self.window!.backgroundColor = .white
            
            let nav = UINavigationController(rootViewController:ViewController(style:.plain))
            let nav2 = UINavigationController(rootViewController:ViewController(style:.plain))
            let tabbar = UITabBarController()
            tabbar.viewControllers = [nav, nav2]
            self.window!.rootViewController = tabbar
            
            self.window!.makeKeyAndVisible()
    
  2. 旋转到横屏

  3. 再次旋转到竖屏

期望结果:
正常显示

实际结果:
页面有问题,发生偏移

修复建议:
布局视图加入到非布局父视图时,如果父视图的尺寸有改动,就有需要激发布局子视图的更新。

其他信息:
关于_tgEndLayoutAction回调,由于调用后就清空,且_tgRotationToDeviceOrientationAction在相同设备方向只会调用一次。但是实际测试中发现,layoutSubviews会多次调用,导致没有回调获取真实尺寸。建议添加Api可以在layoutSubviews出发就触发,已获得最终真实尺寸。

测试环境iOS13, FlowLayout 的 对齐问题

将 FlowLayout 的 tg_gravity 属性设置为 TGGravity.horz.right 的同时,再设置 tg_hspace的话,会出现右边纵向无法对齐的问题,y轴的差距应该就是来自由 tg_hspace设置的值

【需求】流动布局`TGFloatLayout`添加动态边距

功能需求

环境 版本
Xcode Version 11.2.1 (11B53)
Swift 5.0
设备信息 IPhoneX
设备版本 13.2.2

需求描述:
|[边距] 【视图A】[边距] 【视图B】[边距] |
需求3个边距需要按父视图宽度进行均分

目前替代实现方法:
1.必须知道视图A,B的宽度。
2.计算实际应该显示的边距宽度。
3.设置tg_leftPaddingtg_rightPadding(其中space会自动浮动间距)

install TangramKit,Insufficient authority!

Sandbox: rsync.samba(25717) deny(1) file-write-create /Users/Library/Developer/Xcode/DerivedData/CloudMusic-fdvxzxbqcgtptwcjdyjypaykooks/Build/Products/Debug-iphonesimulator/CloudMusic.app/Frameworks/TangramKit.framework/_CodeSignature

How to solve it?

Runtime Height

Hi everyone.

I added few subviews to TGLinearLayout. How can I get total calculated height of all layout? For using in UITableView

動畫 Resize

請問在 TGLinearLayout 裡面其中一個 view 大小的時候
整個佈局有辦法以動畫方式重新 resize嗎

在Controller中合适才可以拿到准确的frame?

我是按照demo,view放在loadView写的。并且修改了self.view
我需要添加一个CAShapeLayer,所以需要知道子控件尺寸。
我在viewDidLayoutSubviews下拿到的通过wrap的高度为0.
请问这种情况在正常生命周期下,应该在哪里才可以获取所有控件的正确frame呢?

子视图联合布局

我企图给定父视图的高度,两个子视图给定间隔且等高来平分剩余高度。但是貌似第一个视图必须是独立能根据自身限定确定布局的。子视图能否这样联合布局?
不知道说清楚没有,程序员还是用代码交流吧:
S = TGRelativeLayout()
S.backgroundColor = UIColor.lightGray
S.tg_width.equal(100)
S.tg_height.equal(400)
S.tg_top.equal(64)
view.addSubview(S)
A = UIView()
C = UIView()
C.backgroundColor = UIColor.blue
A.backgroundColor = UIColor.red
A.tg_left.equal(0).and().tg_right.equal(0).and().tg_top.equal(10)
//A没有给定高度,和C等高来平分S剩余空间
C.tg_left.equal(0).and().tg_right.equal(0).and().tg_top.equal(A.tg_bottom).offset(10).and().tg_bottom.equal(10)
C.tg_height.equal(A.tg_height)//A和C等高
S.addSubview(A)
S.addSubview(C)

发现一个很有趣的库和TangramKit结合起来应该很棒

布局高度问题,希望作者解答一下

主 TGLinearLayout(.vert),添加两个2子布局,子布局1:TGLinearLayout(.vert)嵌套uibutton和uilabel,子布局2:TGLinearLayout(.horz),嵌套uibutton,结果:子布局1跟子布局2出现重叠,
image

布局高度问题,希望还能得到作者回复

希望得到以下2个问题的答复

如图,v1和v2只会显示出一个,通过界面查看,v2的高度为0
使用TGRelativeLayout,然后使用v2.tg_height.equal(v1.tg_height)就能看到高度,但是使用TGLinearLayout确看不到高度不显示,不知道这是为什么,但是使用v2.tg_height.equal(v1.tg_height.numberVal)就正常
s

还有第二个问题,就是自定义UIView当中使用布局,放到UIViewController中,布局高度为0,都重叠在了一起,代码和截图如下
我想要的效果是,我在自定义UIView中使用TGLinearLayout布局,然后在将其加入Controller中的TGLinearLayout,会自动撑开,我UILabel以及UIView都设置了.wrap,如图可看
e
r
d

布局动画问题

有的时候页面没有开启动画,但是在模拟器上运行就有布局动画,但是在真机上就不存在布局动画,不知道是什么原因导致的

在cell中添加TGBaseLayout的点击事件问题

在UITableViewCell中添加了一个TGRelativeLayout,并tg_setTarget设置了点击事件

但是点击TGRelativeLayout时,cell本身的点击事件(tableView didSelectRowAt)也会被调用

建议添加一个tg_xx属性,以控制是否让tg_setTarget的点击事件向下传递给父控件

为什么蓝色和红色View的高度不一致?

override func viewDidLoad() {
        super.viewDidLoad()

        let S = TGRelativeLayout()
        let A = UILabel()
        let B = UILabel()

        S.tg_width.equal(300).and().tg_height.equal(300)
        
        S.backgroundColor = .yellow
        
        A.text = "Hello world"
        A.backgroundColor = .blue
        
        A.tg_left.equal(0)
        A.tg_top.equal(0)
        A.tg_height.equal(40)
        A.tg_right.equal(B.tg_left).offset(10)

        B.text = "Hello world2"
        B.backgroundColor = .red
        
        B.tg_right.equal(0)
        B.tg_top.equal(0)
        B.tg_width.equal(.wrap)
        B.tg_height.equal(40)

         S.addSubview(A)
        S.addSubview(B)
        
        view.addSubview(S)
    }

2017-01-13 14 30 34

我设置了相同的高度了

A.tg_height.equal(40)
B.tg_height.equal(40)

CELL复用问题

请问替代TableView 和CollectionView的方案里,是否有CELL的自动复用。如果没有的话,是否可能会内存溢出呢?

你好,我是跟着你的框架学的ios开发,有一个问题想请教一下

用的你的框架,感觉很好用,现在有一个问题不知道怎么解决:

我现在的布局的尺寸写死的都是以375的设计图,比如这样 self.tg_top.equal(100)的代码到处都是。在自己的xs上显示是正常的,但是到6sp的系统上运行位置就会错误。

然后我百度查了一下,用下面的代码填上6sp和xs显示的位置都正常了
self.tg_top.equal(floor(CGFloat(Float(100) * Float((UIScreen.main.bounds.width/375.0)))))`

这里我试过了用百分比,但内边距self.tg_rightPadding并不能用百分比设置,就会导致内边距xs和6sp错位

请问是不是有更好的办法呢?不使用我百度查到的方法。
看文档中说的SizeClass是不是和我的问题有关?
我不是很能理解SizeClass怎么用,这里好像只和横竖屏的配置有关?

在UIScrollView中使用TGLinearLayout进行布局,当布局中使用到从xib加载出来的view时,view的高度异常。

当使用如下代码进行布局后,linearLayout 的高度为74(这是正确的),assignView的高度却变成了138(正确应该是64)。大致代码如下:

        let scrollView = UIScrollView()
        scrollView.frame = CGRect(x: 0, y: 64, width: 300, height: 300)
        scrollView.backgroundColor = UIColor.lightGray
        scrollView.showsVerticalScrollIndicator = false
        slef.view.addSubview(scrollView)

        let linearLayout = TGLinearLayout(.vert)
        linearLayout.tg_size(width: .fill, height: .wrap)
        
        // 从xib里加载出来的view
        let assignView = Bundle.main.loadNibNamed("AssignView", owner: nil, options: nil)!.last as! AssignView
        assignView.tg_size(width: .fill, height: 64)
        assignView.tg_bottom.equal(10)
        linearLayout.addSubview(assignView)
        
        scrollView.addSubview(linearLayout) 

tg.left 比tg_left更加符合链式语法。

    let S = TGLinearLayout(.vert)
    S.tg.vspace = 10
    S.tg.width.equal(100)
    S.tg.height.equal(.wrap)

    let A = UIView()
    A.tg.left.equal(20%)
    A.tg.right.equal(30%)
    A.tg.height.equal(A.tg.width)
    S.addSubview(A)

    let B = UIView()
    B.tg.left.equal(40)
    B.tg.width.equal(.fill)
    B.tg.height.equal(40)
    S.addSubview(B)

    let C = UIView()
    C.tg.width.equal(.fill)
    C.tg.height.equal(40)
    S.addSubview(C)

    let D = UIView()
    D.tg.right.equal(20)
    D.tg.width.equal(50%)
    D.tg.height.equal(40)
    S.addSubview(D)

tg_height 高度 设置weight bug?

override func viewDidLoad() {
super.viewDidLoad()

// view.addSubview(rootLayout)
//
// let homeVC = HomeViewController()
// addChildViewController(homeVC, toContainerView: rootLayout.homeView)
//
// let tabVC = MainTabViewController()
// addChildViewController(tabVC, toContainerView: rootLayout.tabView)

    let linearLayout = TGLinearLayout(frame: self.view.frame, orientation: .vert)
    
    self.view.addSubview(linearLayout)
    
    
    let l2 = TGLinearLayout(.vert)
    l2.tg_width.equal(.fill)
    l2.tg_height.equal(10%)
    
    l2.backgroundColor = UIColor.red
    
    linearLayout.addSubview(l2)
    
}

这里 高度不是10% 而是全屏

tg_sizeThatFits结果不准的问题

<TGLinearLayout>
	<TGLinearLayout>之前的示例代码</TGLinearLayout>
	<UILabel numberOfLines=0></UILabel>
</TGLinearLayout>

这种布局情况会出现tg_sizeThatFits结果不准确。

image

button, label默认不是自适应的

我的理想状态是不用写.wrap

    descLabel.tg_top.equal(titleLabel.tg_bottom, offset: 5)
    descLabel.tg_centerX.equal(rootLayout.tg_centerX, offset: 0)
    descLabel.tg_height ~= .wrap
    descLabel.tg_width ~= .wrap

    remindButton.tg_bottom.equal(rootLayout.tg_bottom, offset: 20)
    remindButton.tg_right.equal(rootLayout.tg_right, offset: 10)
    remindButton.tg_width ~= .wrap
    remindButton.tg_height ~= .wrap

tg_width以及and()

正如其他人也提了这个问题, 外层的tg已经提供nameSpace了,后面的为什么不采用left,right,width之类的更为简洁和易于理解了?而且对于函数式编程这个特点来说, and(),还是有明显的smalltalk语法的影子啊,这要是OC版本无可厚非,Swift这样就不友好了。

Swift4

是否有计划进行swift4的支持

TGFlowLayout 子视图平均布局,宽高相等

请问这样的子视图怎么设置,或者父视图怎么设置?
ps:
其实就是利用TGFlowLayout设计9宫格布局[但是不完全只有9个子视图,可能[0-n],是需要动态添加的]

Code

imageLayout = TGFlowLayout(.vert, arrangedCount: 3)
        imageLayout.tg_space = 5
        imageLayout.tg_height.equal(.wrap)
        imageLayout.tg_gravity = TGGravity.horz.fill
        imageLayout.tg_width.equal(.fill)

当加入子视图时候.自动宽高相等

相对布局时,设置宽度为.wrap的UILabel,其他视图参照Label的高度设置高度时,高度设置无效

    如下代码,根据label的高度设置view的高度,正确的结果是红色的view尺寸完全等于label的尺寸,但是,实际的结果是view的高度只覆盖了label的第一行。

    let view = UIView()
    rootLayout.addSubview(view)
    
    let label = UILabel()
    rootLayout.addSubview(label)
    
    label.tg_left.equal(10)
    label.tg_width.equal(.wrap).max(100)
    label.tg_height.equal(.wrap)
    
    view.tg_top.equal(label.tg_top)
    view.tg_bottom.equal(label.tg_bottom)
    view.tg_left.equal(label.tg_left)
    view.tg_right.equal(label.tg_right)
    
    label.text = "测试12345660392034323"
    view.backgroundColor = UIColor.red

NameSpace

建议使用命名空间的方式使用自定义的扩展属性

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.