Swift - Keep UIImageView in the same position on rotate - ios

I have UIWebView and in its scrollView, I added a UIImageView like so:
self.webview.scrollView.addSubview(image)
my problem is when I rotate my device from portrait to landscape the UIImageView does not stay at the position I originally set it to on the scrollView, I understand the width and height of the screen change, I guess what I am trying to do it change the the position on my UIImageView so it appears it did not change.
I have this method in place:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
var newScrollViewFrame = webview.scrollView.frame
var newFrame = webview.frame
newFrame.size.width = size.width
newFrame.size.height = size.height
newScrollViewFrame.size.width = size.width
newScrollViewFrame.size.height = size.height
webview.frame = newFrame
webview.scrollView.frame = newScrollViewFrame
}
The current code inside this method just resize the UIWebView and its scroll view, but not the UIImageViews in the scrollView
Any help would be appreciated.
Thanks,
I have tried the following:
for views in webview.scrollView.subviews
{
if(views.isKindOfClass(UIImageView))
{
views.transform = CGAffineTransformMakeRotation(CGFloat(M_PI)/2);
}
}
but this puts on UIImageView sideways on rotate
Here is how I am adding the webview to the view:
webview = UIWebView()
webview.frame = self.view.bounds
webview.scrollView.frame = webview.frame
webview.userInteractionEnabled = true
webview.scalesPageToFit = true
webview.becomeFirstResponder()
webview.delegate = self
webview.scrollView.delegate = self
self.view.addSubview(webview)
I have half solved my problem, but doing the following:
webview.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
view.addConstraint(horizontalConstraint)
let verticalConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)
view.addConstraint(verticalConstraint)
let widthConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0.1, constant: 500)
view.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 500)
view.addConstraint(heightConstraint)
However now, the UIWebView is not full width or height :( Sooooo close.
I also tried this, but the UIImageView do not remain in the same spot.
let left = NSLayoutConstraint(item: self.webView, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: self.webView, attribute: .Right, relatedBy: .Equal, toItem: self.view, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: self.webView, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
let bottom = NSLayoutConstraint(item: self.webView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: 0)
NSLayoutConstraint.activateConstraints([top, bottom, left, right])
I have also tried adding constraints to the UIImageView
let stampView:StampAnnotation = StampAnnotation(imageIcon: UIImage(named: "approved.png"), location: CGPointMake(currentPoint.x, currentPoint.y))
self.webview.scrollView.addSubview(stampView)
let left = NSLayoutConstraint(item: stampView, attribute: .Left, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Left, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: stampView, attribute: .Right, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: stampView, attribute: .Top, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Top, multiplier: 1, constant: 0)
let bottom = NSLayoutConstraint(item: stampView, attribute: .Bottom, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Bottom, multiplier: 1, constant: 0)
NSLayoutConstraint.activateConstraints([top, bottom, left, right])
same result, UIImageView does not stay in the same spot.
UPDATE
My webview:
webview = UIWebView()
webview.userInteractionEnabled = true
webview.scalesPageToFit = true
webview.becomeFirstResponder()
webview.delegate = self
webview.scrollView.delegate = self
self.view.addSubview(webview)
webview.loadRequest(NSURLRequest(URL:url))
webview.gestureRecognizers = [pinchRecognizer, panRecognizer]
webview.translatesAutoresizingMaskIntoConstraints = false
let left = NSLayoutConstraint(item: webview, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: webview, attribute: .Right, relatedBy: .Equal, toItem: self.view, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: webview, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
let bottom = NSLayoutConstraint(item: webview, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: 0)
NSLayoutConstraint.activateConstraints([top, bottom, left, right])
UIImageView
stampView.translatesAutoresizingMaskIntoConstraints = false
let left = NSLayoutConstraint(item: stampView, attribute: .Left, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Left, multiplier: 1, constant: 100)
let right = NSLayoutConstraint(item: stampView, attribute: .Right, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: stampView, attribute: .Top, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Top, multiplier: 1, constant: 100)
let bottom = NSLayoutConstraint(item: stampView, attribute: .Bottom, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Bottom, multiplier: 1, constant: 0)
let width = NSLayoutConstraint(item: stampView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0.1, constant: 150)
let height = NSLayoutConstraint(item: stampView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 73)
NSLayoutConstraint.activateConstraints([left, right, top, bottom, width, height])
I just need to figure out the math to have this device be at the position of touch. (in percentages ?)

I think these things are always easier to do without using autolayout. To do this, I recomend using viewDidLayoutSubviews(). Here is my code:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
webView.frame = view.bounds
let screen = UIScreen.mainScreen().fixedCoordinateSpace
//These values will give a rect half the size of the screen and centered.
let width = screen.bounds.width / 2
let height = screen.bounds.height / 2
let x = (screen.bounds.width - width) / 2
let y = (screen.bounds.height - height) / 2
let absoluteRect = CGRect(x: x, y: y, width: width, height: height)
let stampRect = screen.convertRect(absoluteRect, toCoordinateSpace: webView)
stampView.frame = stampRect
//Change the orientation of the image
switch UIDevice.currentDevice().orientation {
case .LandscapeLeft:
stampView.image = UIImage(CGImage:originalImage.CGImage!, scale:originalImage.scale, orientation: UIImageOrientation.Left)
break
case .LandscapeRight:
stampView.image = UIImage(CGImage:originalImage.CGImage!, scale:originalImage.scale, orientation: UIImageOrientation.Right)
break
default:
stampView.image = UIImage(CGImage:originalImage.CGImage!, scale:originalImage.scale, orientation: UIImageOrientation.Up)
break
}
}
I am doing several things here...First I set the webViewFrame. Next, it is helpful here to define an absolute coordinate system relative to your screen. When the phone orientation changes, the values of screen will not change (allowing you to keep your imageView in the same place.) Next I define the desired frame for the stampView, then convert the absolute frame into its equivalent inside your scrollView (it's superView) and assign it to the stampView. Finally, if you want the image in your stampView to always be oriented correctly, you need to change the image orientation. CGAffineTransformMakeRotation only works if your view is square, but we can make it more general by actually changing the imageOrientation within the stampView. This requires a property for the original image:
let originalImage = UIImage(named: "image_name")!
Finally, because viewWillLayoutSubViews() is not called for landscape to landscape transitions, do the following:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
view.setNeedsLayout()
}
This code doesn't make for the prettiest transitions, it should help with your layout problems.

To make the UIImageView keep the same size and stay in the same position relative to the UIWebView, you can set your views to be a percentage of their respective superView. Here I've created some mock views that illustrate the basic idea:
import UIKit
class ViewController: UIViewController {
//we create some views for testing and create references to the size and points we need for positioning
let webView = UIWebView()
let image = UIImageView()
let image2 = UIImageView()
var imageViewSize = CGSize()
var imageViewCenter = CGPoint()
override func viewDidLoad() {
super.viewDidLoad()
//set webView frame
webView.frame = self.view.bounds
webView.backgroundColor = UIColor.clearColor()
webView.userInteractionEnabled = true
webView.scalesPageToFit = true
webView.opaque = false
self.view.addSubview(webView)
//we will hold onto the original size of the UIImageView for later
imageViewSize = CGSizeMake(webView.bounds.size.width * 0.2, webView.bounds.size.height * 0.1)
//mock UIImageView
image.backgroundColor = UIColor.orangeColor()
image.frame.size = CGSizeMake(imageViewSize.width, imageViewSize.height)
image.center = CGPointMake(webView.bounds.size.width / 2, webView.bounds.size.height / 2)
webView.scrollView.addSubview(image)
//I've created a subset image to illustrate the orientation
image2.backgroundColor = UIColor.whiteColor()
image2.frame = CGRectMake(10, 10, 10, 10)
image.addSubview(image2)
}
And then change the frame when rotated (Notice that the position on the UIImageView and the width of the UIWebView are set relative to the height of their superViews and vice versa since the device is rotated):
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
image.frame.size = CGSizeMake(imageViewSize.width, imageViewSize.height)
image.center = CGPointMake(webView.bounds.size.height / 2, webView.bounds.size.width / 2)
webView.frame = CGRectMake(0, 0, self.view.bounds.size.height, self.view.bounds.size.width)
webView.scrollView.contentSize = webView.frame.size
}
}
Since you are creating the position and sizes of your views as percentages of their superViews, the code will play nicer with different device sizes (i.e. iPhone/iPad).

Related

WKWebView - Ignore the right "safe area inset" in landscape view

I am fairly new to iOS development and I'm using a WKWebView to render my website. I am trying to add some constraints but want to ignore the right "safe area inset" in landscape view as marked in the screenshot.
Here is the screenshot.
Here is the code.
let webConfiguration = WKWebViewConfiguration()
let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: 0.0, height: self.webViewContainer.frame.size.height))
self.webView = WKWebView (frame: customFrame , configuration: webConfiguration)
webView.translatesAutoresizingMaskIntoConstraints = false
self.webViewContainer.addSubview(webView)
addConstraints(to: webView, with: webViewContainer)
func addConstraints(to webView: UIView, with superView: UIView) {
webView.translatesAutoresizingMaskIntoConstraints = false
let leadingConstraint = NSLayoutConstraint(item: webView, attribute: .leading, relatedBy: .equal, toItem: superView, attribute: .leading, multiplier: 1, constant: 0)
let trailingConstraint = NSLayoutConstraint(item: webView, attribute: .trailing, relatedBy: .equal, toItem: superView, attribute: .trailing, multiplier: 1, constant: 0)
let topConstraint = NSLayoutConstraint(item: webView, attribute: .top, relatedBy: .equal, toItem: superView, attribute: .top, multiplier: 1, constant: 0)
let bottomConstraint = NSLayoutConstraint(item: webView, attribute: .bottom, relatedBy: .equal, toItem: superView, attribute: .bottom, multiplier: 1, constant: 0)
superView.addConstraints([leadingConstraint, trailingConstraint, topConstraint, bottomConstraint])
}
Any help will be appreciated.
Use size classes and change the constraint like below in the image

Constraints were ignored when trying to implement constraints programmatically

I'm trying to center a logoImage horizontally & vertically by setting constraints but when tested, It was displayed on (x:0, y:0).
Any idea how to fix this?
Thanks
var movieView : UIView?
let logoImage = UIImageView(image: #imageLiteral(resourceName: "my_logo"))
// This function runs in viewWillAppear
internal func setupIntroMovie() {
movieView = UIView(frame: view.frame)
view.addSubview(movieView!)
view.addSubview(logoImage)
let horizontalConstraint = NSLayoutConstraint(item: logoImage,
attribute: .centerX,
relatedBy: .equal,
toItem: view,
attribute: .centerX,
multiplier: 1,
constant: 0)
let verticalConstraint = NSLayoutConstraint(item: logoImage,
attribute: .centerY,
relatedBy: .equal,
toItem: view,
attribute: .centerY,
multiplier: 1,
constant: 0)
view.addConstraints([horizontalConstraint,
verticalConstraint])
updateViewConstraints()
}
You need to set logoImage.translatesAutoresizingMaskIntoConstraints = false as it determines whether the view’s autoresizing mask is translated into Auto Layout constraints.
internal func setupIntroMovie() {
movieView = UIView(frame: view.frame)
view.addSubview(movieView!)
view.addSubview(logoImage)
let horizontalConstraint = NSLayoutConstraint(item: logoImage,
attribute: .centerX,
relatedBy: .equal,
toItem: view,
attribute: .centerX,
multiplier: 1,
constant: 0)
let verticalConstraint = NSLayoutConstraint(item: logoImage,
attribute: .centerY,
relatedBy: .equal,
toItem: view,
attribute: .centerY,
multiplier: 1,
constant: 0)
// Update
logoImage.translatesAutoresizingMaskIntoConstraints = false
view.addConstraints([horizontalConstraint,
verticalConstraint])
updateViewConstraints()
}
If this property’s value is true, the system creates a set of
constraints that duplicate the behavior specified by the view’s
autoresizing mask. This also lets you modify the view’s size and
location using the view’s frame , bounds , or center properties,
allowing you to create a static, frame-based layout within Auto
Layout.

How to make a view scroll against a scrollview animation?

So I have a UIView and I want to have it animate a translation in the opposite direction of the scrollviews scroll animation. How would I go about doing this? Of course this should be depend on the scrollview.contentOffset I think anyway. So if you scroll the other way it goes back to it's place. So the translation is dependent on how far the user scrolls. I am trying to use the following code. Also note that the UIView I currently do not have as a child of the scrollview. It is suppose to stay on screen at all time, but change positions.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.x >= scrollView.contentSize.width {
UIView.animate(withDuration: 2.0, animations: {
self.view.layoutIfNeeded()
})
}
A simple solution would be:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let percentage = scrollView.contentOffset.x / scrollView.contentSize.width
self.box.frame.origin.x = UIScreen.main.bounds.width * percentage
}
Just calculate the percentage of the contentSize that you have scrolled and set the X position to the same percentage of the screen width.
It could do with some improvements to make sure the view doesn't go beyond the bounds of the screen in certain conditions. So you may need to factor in the width of the box in the calculations as an enhancement.
Here is the code I used for testing, The background image is a 4K wallpaper image.
class ViewController: UIViewController {
var box = UIView()
var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView = UIScrollView()
self.scrollView.translatesAutoresizingMaskIntoConstraints = false
self.scrollView.delegate = self
self.view.addSubview(self.scrollView)
NSLayoutConstraint(item: scrollView, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: scrollView, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: scrollView, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: scrollView, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = UIImage(named: "background")
self.scrollView.addSubview(imageView)
NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: scrollView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: imageView, attribute: .left, relatedBy: .equal, toItem: scrollView, attribute: .left, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: imageView, attribute: .right, relatedBy: .equal, toItem: scrollView, attribute: .right, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: imageView, attribute: .bottom, relatedBy: .equal, toItem: scrollView, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
box.frame = CGRect(x: 0, y: UIScreen.main.bounds.height - 110, width: 100, height: 100)
box.backgroundColor = .black
self.view.addSubview(box)
}
}
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let percentage = scrollView.contentOffset.x / scrollView.contentSize.width
let xPosition = UIScreen.main.bounds.width * percentage
self.box.frame.origin.x = xPosition
}
}

Adding leading constraint programmatically crashes app

I'm trying to get my head around how adding constraints programmatically works. So far I have my code like so:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//addViewStandard()
addConstraintsView()
}
func addConstraintsView() {
let someView = UIView(frame: CGRect.zero)
someView.backgroundColor = UIColor.blue
// I want to mimic a frame set of CGRect(x: 20, y: 50, width: 50, height: 50)
let widthConstraint = NSLayoutConstraint(item: someView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50)
let heightConstraint = NSLayoutConstraint(item: someView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50)
let leadingConstraint = NSLayoutConstraint(item: someView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 20)
someView.translatesAutoresizingMaskIntoConstraints = false
someView.addConstraints([widthConstraint, heightConstraint, leadingConstraint])
view.addSubview(someView)
}
}
Now when I run the app it crashes because of the leading constraint. The error message is "Impossible to set up layout with view hierarchy unprepared for constraint". What am I doing wrong here? Should I be adding the constraints to the object (the blue box on this case) or adding them to its superview?
EDIT:
After code changes I have:
func addConstraintsView() {
let someView = UIView(frame: CGRect.zero)
someView.backgroundColor = UIColor.blue
view.addSubview(someView)
someView.translatesAutoresizingMaskIntoConstraints = false
let widthConstraint = NSLayoutConstraint(item: someView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50)
let heightConstraint = NSLayoutConstraint(item: someView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50)
let leadingConstraint = NSLayoutConstraint(item: someView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: 20)
someView.addConstraints([widthConstraint, heightConstraint])
view.addConstraints([leadingConstraint])
}
First of all,
view.addSubview(someView)
someView.translatesAutoresizingMaskIntoConstraints = false
should come before the constraints phase; you have to apply the constraints AFTER someView is added to its superview.
Also, if you are targeting iOS 9, I'd advise you to use layout anchors like
let widthConstraint = someView.widthAnchor.constraint(equalToConstant: 50.0)
let heightConstraint = someView.heightAnchor.constraint(equalToConstant: 50.0)
let leadingConstraint = someView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20.0)
NSLayoutConstraint.activate([widthConstraint, heightConstraint, leadingConstraint])
This way you don't have to worry about which view to apply the constraints to.
Finally (and to clear up your doubt), if you can't use layout anchors, you should add the leading constraint to the superview, not the view.

How to create Auto layout equal width constraint programmatically in ios swift?

How to give programmatically constraints equal width and equal height with multiple views.I check google but not perfect answer for programmatically equal width and height constraints through auto layout.
my code look like below:
var countNoOfViews:Int = 3
#IBOutlet var viewForRow1: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.specialButtonViewLeft()
}
func specialButtonViewLeft(){
for i in 0..<countNoOfViews{
var customView:UIView!
customView = UIView(frame: CGRect.zero)
customView.translatesAutoresizingMaskIntoConstraints = false
viewForRow1.addSubview(customView)
let widthConstraint = NSLayoutConstraint(item: customView, attribute: .width, relatedBy: .equal,toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 20.0)
let topConstraint = NSLayoutConstraint(item: customView, attribute: .top, relatedBy: .equal,toItem: self.viewForRow1, attribute: .top, multiplier: 1.0, constant: 0)
let bottomConstraint = NSLayoutConstraint(item: customView, attribute: .bottom, relatedBy: .equal,toItem: self.viewForRow1, attribute: .bottom, multiplier: 1.0, constant: 0)
let leadingConstraint = NSLayoutConstraint(item: customView, attribute: .leading, relatedBy: .equal, toItem: self.viewForRow1, attribute: .leading, multiplier: 1, constant: customLeadingSpaceLeft)
customLeadingSpaceLeft = customLeadingSpaceLeft + customViewWidth
arrayLeftBtnConstraints.append(widthConstraint)
if i == 0{
customView.backgroundColor = UIColor.red
}else if i == 1{
customView.backgroundColor = UIColor.green
}else if i == 2{
leftViewVal = customLeadingSpaceLeft
customView.backgroundColor = UIColor.black
}
customView.alpha = 0.50
viewForRow1.addConstraints([widthConstraint, leadingConstraint,topConstraint,bottomConstraint])
}
}
I want to add equal width constraint programmatically.
You have three possible ways to do that:
1) By using anchors:
view.widthAnchor.constraint(equalTo: otherView.widthAnchor, multiplier: 1.0).isActive = true
2) Visual format:
simple example - "H:|[otherView]-[view(==otherView)]|"
3) "Old school" constraints:
NSLayoutConstraint(item: #view, attribute: .width, relatedBy: .equal, toItem: #otherView, attribute: .width, multiplier: 1.0, constant: 0.0).isActive = true
hope it will help somebody.
Try this:
let widthConstraint = NSLayoutConstraint(item: customView, attribute: .width, relatedBy: .equal, toItem: viewForRow1, attribute: .width, multiplier: 0.25, constant: 0.0)
multiplier: 0.25, denotes that customView's width will be 1/4th of the parent view, viewForRow1.

Resources