Skip to content

Instantly share code, notes, and snippets.

@krin-san
Last active October 1, 2020 07:23
Show Gist options
  • Save krin-san/bedcf62428d00e2ee22c5d8e2649277f to your computer and use it in GitHub Desktop.
Save krin-san/bedcf62428d00e2ee22c5d8e2649277f to your computer and use it in GitHub Desktop.
NSLayoutConstraint with a two possible states and a flag to toggle between them
#import <UIKit/UIKit.h>
/// This constraint could be toggled between two values (min/max) by `enlarged` flag
@interface ToggleConstraint : NSLayoutConstraint
/**
Max size of the height/width/offset/etc.
Think about it as some UI element can change it's size between min and max values.
*/
@property (nonatomic, assign) IBInspectable BOOL enlarged;
@property (nonatomic, assign) IBInspectable CGFloat minValue;
@property (nonatomic, assign) IBInspectable CGFloat maxValue;
@end
@implementation FWToggleConstraint
#pragma mark - Init
+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c {
ToggleConstraint *constraint = [super constraintWithItem:view1 attribute:attr1 relatedBy:relation toItem:view2 attribute:attr2 multiplier:multiplier constant:c];
[constraint initDefaultValues];
[constraint updateConstant];
return constraint;
}
- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder {
id response = [super awakeAfterUsingCoder:aDecoder];
[self initDefaultValues];
[self updateConstant];
return response;
}
- (void)initDefaultValues {
_enlarged = NO;
_minValue =
_maxValue = 0.;
}
#pragma mark - Bindings
- (void)setEnlarged:(BOOL)enlarged {
BOOL changed = (_enlarged != enlarged);
_enlarged = enlarged;
if (changed) {
[self updateConstant];
}
}
- (void)setMinValue:(CGFloat)value {
BOOL changed = (_minValue != value);
_minValue = value;
if (changed && !self.enlarged) {
[self updateConstant];
}
}
- (void)setMaxValue:(CGFloat)value {
BOOL changed = (_maxValue != value);
_maxValue = value;
if (changed && self.enlarged) {
[self updateConstant];
}
}
- (void)updateConstant {
CGFloat constant = (self.enlarged) ? self.maxValue : self.minValue;
[super setConstant:constant];
[(UIView *)self.firstItem setNeedsLayout];
[(UIView *)self.secondItem setNeedsLayout];
}
@end
import UIKit
class ToggleConstraint: NSLayoutConstraint {
@IBInspectable var minValue: CGFloat = 0 {
didSet {
if oldValue != minValue {
updateConstant()
}
}
}
@IBInspectable var maxValue: CGFloat = 0 {
didSet {
if oldValue != maxValue {
updateConstant()
}
}
}
@IBInspectable var enlarged: Bool = false {
didSet {
if oldValue != enlarged {
updateConstant()
}
}
}
override func awakeAfterUsingCoder(aDecoder: NSCoder) -> AnyObject? {
let response = super.awakeAfterUsingCoder(aDecoder)
updateConstant()
return response
}
private func updateConstant() {
super.constant = enlarged ? maxValue : minValue
(firstItem as? UIView)?.setNeedsLayout()
(secondItem as? UIView)?.setNeedsLayout()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment