Bim*_*awa 135 iphone objective-c ios nslayoutconstraint
我在一个superview中创建了两个视图,然后在视图之间添加了约束:
_indicatorConstrainWidth = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view2 attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f];
[_indicatorConstrainWidth setPriority:UILayoutPriorityDefaultLow];
_indicatorConstrainHeight = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view2 attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f];
[_indicatorConstrainHeight setPriority:UILayoutPriorityDefaultLow];
[self addConstraint:_indicatorConstrainWidth];
[self addConstraint:_indicatorConstrainHeight];
Run Code Online (Sandbox Code Playgroud)
现在我想用动画更改乘数属性,但我无法弄清楚如何更改多重属性.(我在头文件NSLayoutConstraint.h中的私有属性中找到了_coefficient,但它是私有的.)
如何更改多重属性?
我的解决方法是删除旧约束并添加具有不同值的新约束multipler.
And*_*ber 156
这是Swift中的NSLayoutConstraint扩展,它使得设置新的乘法器变得非常简单:
import UIKit
extension NSLayoutConstraint {
func setMultiplier(multiplier:CGFloat) -> NSLayoutConstraint {
NSLayoutConstraint.deactivateConstraints([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.activateConstraints([newConstraint])
return newConstraint
}
}
Run Code Online (Sandbox Code Playgroud)
在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
}
}
Run Code Online (Sandbox Code Playgroud)
演示用法:
@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()
}
Run Code Online (Sandbox Code Playgroud)
Ja͢*_*͢ck 106
如果您只需要应用两组乘数,那么从iOS8开始,您可以添加两组约束并决定哪些应该在任何时候处于活动状态:
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 ...]
Run Code Online (Sandbox Code Playgroud)
Fru*_*eek 54
该multiplier物业是只读的.您必须删除旧的NSLayoutConstraint并将其替换为新的NSLayoutConstraint以进行修改.
但是,由于您知道要更改乘数,因此可以通过在需要更改(通常更少的代码)时自己乘以常量来更改常量.
Evg*_*nii 48
我用来改变现有布局约束的乘数的辅助函数.它创建并激活新约束并停用旧约束.
struct MyConstraint {
static func changeMultiplier(_ constraint: NSLayoutConstraint, multiplier: CGFloat) -> NSLayoutConstraint {
let newConstraint = NSLayoutConstraint(
item: constraint.firstItem,
attribute: constraint.firstAttribute,
relatedBy: constraint.relation,
toItem: constraint.secondItem,
attribute: constraint.secondAttribute,
multiplier: multiplier,
constant: constraint.constant)
newConstraint.priority = constraint.priority
NSLayoutConstraint.deactivate([constraint])
NSLayoutConstraint.activate([newConstraint])
return newConstraint
}
}
Run Code Online (Sandbox Code Playgroud)
用法,将乘数改为1.2:
constraint = MyConstraint.changeMultiplier(constraint, multiplier: 1.2)
Run Code Online (Sandbox Code Playgroud)
小智 39
Objective Schriber的Objective-C版本答案
为NSLayoutConstraint类创建类别,并将此方法添加到.h文件中
#import <UIKit/UIKit.h>
@interface NSLayoutConstraint (Multiplier)
-(instancetype)updateMultiplier:(CGFloat)multiplier;
@end
Run Code Online (Sandbox Code Playgroud)
在.m文件中
#import "NSLayoutConstraint+Multiplier.h"
@implementation NSLayoutConstraint (Multiplier)
-(instancetype)updateMultiplier:(CGFloat)multiplier {
[NSLayoutConstraint deactivateConstraints:[NSArray arrayWithObjects:self, nil]];
NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:self.firstItem attribute:self.firstAttribute relatedBy:self.relation toItem:self.secondItem attribute:self.secondAttribute multiplier:multiplier constant:self.constant];
[newConstraint setPriority:self.priority];
newConstraint.shouldBeArchived = self.shouldBeArchived;
newConstraint.identifier = self.identifier;
newConstraint.active = true;
[NSLayoutConstraint activateConstraints:[NSArray arrayWithObjects:newConstraint, nil]];
//NSLayoutConstraint.activateConstraints([newConstraint])
return newConstraint;
}
@end
Run Code Online (Sandbox Code Playgroud)
稍后在ViewController中为要更新的约束创建插座.
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;
Run Code Online (Sandbox Code Playgroud)
并在下面的任何地方更新乘数.
self.topConstraint = [self.topConstraint updateMultiplier:0.9099];
Run Code Online (Sandbox Code Playgroud)
Rob*_*ler 11
正如其他答案所解释的那样:您需要删除约束并创建新约束。
您可以通过为NSLayoutConstraintwithinout参数创建静态方法来避免返回新约束,这允许您重新分配传递的约束
import UIKit
extension NSLayoutConstraint {
static func setMultiplier(_ multiplier: CGFloat, of constraint: inout NSLayoutConstraint) {
NSLayoutConstraint.deactivate([constraint])
let newConstraint = NSLayoutConstraint(item: constraint.firstItem, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: constraint.secondItem, attribute: constraint.secondAttribute, multiplier: multiplier, constant: constraint.constant)
newConstraint.priority = constraint.priority
newConstraint.shouldBeArchived = constraint.shouldBeArchived
newConstraint.identifier = constraint.identifier
NSLayoutConstraint.activate([newConstraint])
constraint = newConstraint
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
@IBOutlet weak var constraint: NSLayoutConstraint!
override func viewDidLoad() {
NSLayoutConstraint.setMultiplier(0.8, of: &constraint)
// view.layoutIfNeeded()
}
Run Code Online (Sandbox Code Playgroud)
小智 10
您可以更改"常量"属性,以通过一点点数学实现相同的目标.假设约束的默认乘数是1.0f.这是Xamarin C#代码,可以很容易地转换为objective-c
private void SetMultiplier(nfloat multiplier)
{
FirstItemWidthConstraint.Constant = -secondItem.Frame.Width * (1.0f - multiplier);
}
Run Code Online (Sandbox Code Playgroud)
Đor*_*vić 10
斯威夫特 5+
根据Evgenii 的 回答,这是一种改变multiplierthrough的优雅方法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])
}
}
Run Code Online (Sandbox Code Playgroud)
以及用法:
myConstraint.change(multiplier: 0.6)
Run Code Online (Sandbox Code Playgroud)
在 Swift 5.x 中,您可以使用:
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
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在尝试修改我自己的代码后,上述代码均不适用于我此代码此代码在 Xcode 10 和 swift 4.2 中有效
import UIKit
extension NSLayoutConstraint {
/**
Change multiplier constraint
- parameter multiplier: CGFloat
- returns: NSLayoutConstraintfor
*/i
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
}
}
@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()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
72231 次 |
| 最近记录: |