Hi I am developing iPhone application in which I tried to set one side border for edittext. I did this in following way:
int borderWidth = 1;
CALayer *leftBorder = [CALayer layer];
leftBorder.borderColor = [UIColor whiteColor].CGColor;
leftBorder.borderWidth = borderWidth;
leftBorder.frame = CGRectMake(0, textField.frame.size.height - borderWidth, textField
.frame.size.width, borderWidth);
[textField.layer addSublayer:leftBorder];
I put some constraints on my edittext in IB so that when I rotate my device it will adjust width of text field according to that. My problem is that adjusts the width of edittext not adjusting the width of CALayer which I set for my edit text. So I think I have to put some constraints for my CALayer item as well. But I dont know how to do that. ANy one knows about this? Need Help. Thank you.
Checkout this solution. Use KVO, for the path "YourView.bounds" as given below.
Then handle it as given below.
For more info, refer the following link.
https://theswiftdev.com/2015/03/28/auto-layout-with-layers/
Swift 3.x KVO Solution (Updated @arango_86's answer)
Add Observer
Observe Values
My solution when I create with dashed border
I had a similar problem - needing to set the frame of a 'CALayer' when using auto layout with views (in code, not IB).
In my case, I had a slightly convoluted hierarchy, having a view controller within a view controller. I ended up at this SO question and looked into the approach of using
viewDidLayoutSubviews
. That didn't work. Just in case your situation is similar to my own, here's what I found...Overview
I wanted to set the frame for the
CAGradientLayer
of aUIView
that I was positioning as a subview within aUIViewController
using auto layout constraints.Call the subview
gradientView
and the view controllerchild_viewController
.child_viewController
was a view controller I'd set up as a kind of re-usable component. So, theview
ofchild_viewController
was being composed into a parent view controller - call thatparent_viewController
.When
viewDidLayoutSubviews
ofchild_viewController
was called, theframe
ofgradientView
was not yet set.(At this point, I'd recommend sprinkling some
NSLog
statements around to get a feel for the sequence of creation of views in your hierarchy, etc.)So I moved on to try using
viewDidAppear
. However, due to the nested nature ofchild_viewController
I foundviewDidAppear
was not being called.(See this SO question: viewWillAppear, viewDidAppear not being called, not firing).
My current solution
I've added
viewDidAppear
inparent_viewController
and from there I'm callingviewDidAppear
inchild_viewController
.For the initial load I need
viewDidAppear
as it's not until this is called inchild_viewController
that all of the subviews have their frames set. I can then set the frame for theCAGradientLayer
...I've said that this is my current solution because I'm not particularly happy with it.
After initially setting the frame of the
CAGradientLayer
- that frame can become invalid if the layout changes - e.g. rotating the device.To handle this I'm using
viewDidLayoutSubviews
inchild_viewController
- to keep the frame of theCAGradientLayer
withingradientView
, correct.It works but doesn't feel good. (Is there a better way?)
I implemented the method layoutSubviews of my custom view; inside this method I just update each sublayer's frame to match the current boundaries of my subview's layer.
According to this answer,
layoutSubviews
does not get called in all needed cases. I have found this delegate method more effective: