我有一个带有两个NSTextField控件的窗口,其值必须保持彼此同步。具体地,一个是宽度而另一个是长度,它们的比率应保持等于给定的纵横比。我希望用户能够设置他们喜欢的任何一个,并自动进行另一个更新。
我的第一种方法:我将两个控件中的每个控件的委托设置为窗口控制器。我实现了controlTextDidEndEditing方法。我检查发件人。如果是宽度字段,我计算高度字段并通过bound属性更新其值(self.my_height = self.my_width / aspectRatio)。同样,如果它是高度字段,(self.my_width = self.my_height * aspectRatio)。
但是我遇到了障碍。假设纵横比为1.5。用户在宽度字段中输入100,然后移动到另一个字段。高度字段更新为66(无论好坏,我选择总是向下舍入)。用户单击高度字段,不进行任何更改,并在其他位置单击。宽度字段更新为99.用户正在刮他/她的头。我的提炼。我还在窗口控制器中实现了controlTextDidChange方法。所有这一切都将静态(文件作用域)BOOL变量(gTextFieldDidChange)设置为YES。现在,当我输入controlTextDidEndEditing时,我检查gTextFieldDidChange的状态。如果不是,那我立刻回来。如果是,那么我将gTextFieldDidChange清除回NO并处理长度/宽度更新。
这似乎对我没有任何问题,但似乎相当“后门”。 我缺少一种更清洁/更聪明的方法吗?
感谢任何/所有建议。 麦克
答案 0 :(得分:1)
以下代码使用NSTextFieldDelegate>
方法执行您想要的操作:
@interface HASMainViewController () <NSTextFieldDelegate>
@property (weak) IBOutlet NSTextField *widthTextField;
@property (weak) IBOutlet NSTextField *heightTextField;
@property (weak) IBOutlet NSTextField *ratioLabel;
@end
@implementation HASMainViewController
- (void)awakeFromNib {
self.widthTextField.delegate = self;
self.heightTextField.delegate = self;
self.ratioLabel.stringValue = @"1.777777"; // 16:9 (1920 x 1080)
}
- (void)controlTextDidChange:(NSNotification *)obj {
if (obj.object == self.widthTextField) {
// If the width textfield gets changed we want to pass its value and -1 for calculating the height.
// After that we set the height's text field to the calculated value.
self.heightTextField.integerValue = [self calculateRatioComponentWithWidth:self.widthTextField.integerValue height:-1 ratio:self.ratioLabel.doubleValue];
} else if (obj.object == self.heightTextField) {
// If the width textfield gets changed we want to pass its value and -1 for calculating the height.
// After that we set the height's text field to the calculated value.
self.widthTextField.integerValue = [self calculateRatioComponentWithWidth:-1 height:self.heightTextField.integerValue ratio:self.ratioLabel.doubleValue];
}
}
/**
* This method calculates the missing component (determined by "-1") for a given ratio.
*
* @param width An NSInteger representing the width. Pass -1 if this value should be calculated.
* @param height An NSInteger representing the height. Pass -1 if this value should be calculated.
* @param ratio The ratio which needs to be kept.
*
* @return An NSInteger which is depending on the what you passed as parameters the calculated width or height.
*
* @discussion This method raises an HASInternalInconsistencyException exception if both width and height parameters are -1.
*
*/
- (NSInteger)calculateRatioComponentWithWidth:(NSInteger)width height:(NSInteger)height ratio:(double)ratio {
if (width == -1 && height == -1) [[NSException exceptionWithName:@"HASInternalInconsistencyException"
reason:@"Both width and height are -1 (to be calculated)."
userInfo:nil] raise];
// Calculate new width
if (width == -1) return (NSInteger)round(height * ratio);
// Calculate new width
else if (height == -1) return (NSInteger)round(width * 1 / ratio);
// Just to silence the compiler
return 0;
}
@end
您可以从我刚刚为您制作的Bitbucket Repository克隆或下载一个小样本应用; - )
答案 1 :(得分:0)
我实际上找到了比我最初尝试的更好更简单的解决方案,以及HAS的建议。
我只是检查了值绑定下的“持续更新值”框。 这样做意味着在调用controlTextDidChange之前更新绑定值。
我现在可以在键入时进行更正,不再需要延迟调用controlTextDidEndEditting。