Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 830 Vote(s) - 3.53 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Can I change multiplier property for NSLayoutConstraint?

#11
Yes w can change multiplier values just make an extension of NSLayoutConstraint
and use it like ->

func setMultiplier(_ multiplier:CGFloat) -> NSLayoutConstraint {

NSLayoutConstraint.deactivate([self])

let newConstraint = NSLayoutConstraint(
item: firstItem!,
attribute: firstAttribute,
relatedBy: relation,
toItem: secondItem,
attribute: secondAttribute,
multiplier: multiplier,
constant: constant)

newConstraint.priority = priority
newConstraint.shouldBeArchived = shouldBeArchived
newConstraint.identifier = identifier

NSLayoutConstraint.activate([newConstraint])
return newConstraint
}

self.mainImageViewHeightMultiplier = self.mainImageViewHeightMultiplier.setMultiplier(375.0/812.0)

Reply

#12
Here is an NSLayoutConstraint extension in Swift that makes setting a new multiplier pretty easy:

**In Swift 3.0+**

import UIKit
extension NSLayoutConstraint {
/**
Change multiplier constraint

- parameter multiplier: CGFloat
- returns: NSLayoutConstraint
*/
func setMultiplier(multiplier:CGFloat) -> NSLayoutConstraint {

NSLayoutConstraint.deactivate([self])

let newConstraint = NSLayoutConstraint(
item: firstItem,
attribute: firstAttribute,
relatedBy: relation,
toItem: secondItem,
attribute: secondAttribute,
multiplier: multiplier,
constant: constant)

newConstraint.priority = priority
newConstraint.shouldBeArchived = self.shouldBeArchived
newConstraint.identifier = self.identifier

NSLayoutConstraint.activate([newConstraint])
return newConstraint
}
}


Demo usage:

@IBOutlet weak var myDemoConstraint:NSLayoutConstraint!

override func viewDidLoad() {
let newMultiplier:CGFloat = 0.80
myDemoConstraint = myDemoConstraint.setMultiplier(newMultiplier)

//If later in view lifecycle, you may need to call view.layoutIfNeeded()
}
Reply

#13
If you have only have two sets of multipliers that need to be applied, from **iOS8** onwards you can add both sets of constraints and decide which should be active at any time:

NSLayoutConstraint *standardConstraint, *zoomedConstraint;

// ...
// switch between constraints
standardConstraint.active = NO; // this line should always be the first line. because you have to deactivate one before activating the other one. or they will conflict.
zoomedConstraint.active = YES;
[self.view layoutIfNeeded]; // or using [UIView animate ...]

**Swift 5.0 version**


var standardConstraint: NSLayoutConstraint!
var zoomedConstraint: NSLayoutConstraint!

// ...

// switch between constraints
standardConstraint.isActive = false // this line should always be the first line. because you have to deactivate one before activating the other one. or they will conflict.
zoomedConstraint.isActive = true
self.view.layoutIfNeeded() // or using UIView.animate
Reply

#14
in Swift 5.x you can use:

extension NSLayoutConstraint {
func setMultiplier(multiplier: CGFloat) -> NSLayoutConstraint {
guard let firstItem = firstItem else {
return self
}
NSLayoutConstraint.deactivate([self])
let newConstraint = NSLayoutConstraint(item: firstItem, attribute: firstAttribute, relatedBy: relation, toItem: secondItem, attribute: secondAttribute, multiplier: multiplier, constant: constant)
newConstraint.priority = priority
newConstraint.shouldBeArchived = self.shouldBeArchived
newConstraint.identifier = self.identifier
NSLayoutConstraint.activate([newConstraint])
return newConstraint
}
}
Reply

#15
I have a way. No need to re-create a constraint.

Assuming you have an imageView which you want to constraint its aspect ratio to match the image aspect ratio.

1. Create an aspect ratio constraint for the imageView and set multiplier to 1 and constant to 0.
2. Create an outlet for the aspect ratio constraint.
3. Change the constraint constant value at runtime, according the the image you load:

``` Swift
let multiplier = image.size.width / image.size.height
let (w, h) = (imageView.bounds.width, imageView.bounds.height)
let expectedW = h * multiplier
let diff = expectedW - h
imageViewAspectConstraint.constant = image.size.width >= image.size.height ? diff : -diff // multiplier is read-only, but constant is RW
```
Reply

#16
@IBOutlet weak var viewHeightConstraint: NSLayoutConstraint!


let heightOfSuperview = self.view.bounds.height

viewHeightConstraint.constant = heightOfSuperview * 0.5

// this has the same effect as multiplier
Reply

#17
**Swift 5+**

Based on [Evgenii's][1] [answer][2], here is an elegant way to change the `multiplier` through `extension`.

extension NSLayoutConstraint {
func change(multiplier: CGFloat) {
let newConstraint = NSLayoutConstraint(item: firstItem,
attribute: firstAttribute,
relatedBy: relation,
toItem: secondItem,
attribute: secondAttribute,
multiplier: multiplier,
constant: constant)

newConstraint.priority = self.priority

NSLayoutConstraint.deactivate([self])
NSLayoutConstraint.activate([newConstraint])
}
}

And the usage:

myConstraint.change(multiplier: 0.6)

[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#18
Simple answer, no extensions required. I tried for my case, worked fine for me.

So as multiplier is a get only property, we can simply set multiplier in the following way :

yourConstraintOutlet.setValue(yourDesiredMultiplierValue, forKey: "multiplier")

yourConstraintOutlet.setValue(0.75, forKey: "multiplier")
Reply

#19
note that you can simply `yourConstraint.setValue(0.75, forKey: "multiplier")`

or
---

Xcode 13.3.1, Swift 5.6 (swiftlang-5.6.0.323.62 clang-1316.0.20.8)

This is based on @Ullas Pujary's answer and I make it a little swifter and remove the warnings on firstItem` and `secondItem`

```
extension NSLayoutConstraint {
public static func setMultiplier(_ newMultiplier: CGFloat, of constraint: inout NSLayoutConstraint) {
constraint.isActive = false

guard
let firstItem = constraint.firstItem,
let secondItem = constraint.secondItem
else {
return
}


let newConstraint = NSLayoutConstraint(item: firstItem,
attribute: constraint.firstAttribute,
relatedBy: constraint.relation,
toItem: secondItem,
attribute: constraint.secondAttribute,
multiplier: newMultiplier,
constant: constraint.constant)

newConstraint.priority = constraint.priority
newConstraint.shouldBeArchived = constraint.shouldBeArchived
newConstraint.identifier = constraint.identifier

newConstraint.isActive = true
constraint = newConstraint
}
}
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through