NSPredicate 作为约束求解器?

发布于 2024-08-23 05:52:59 字数 1061 浏览 8 评论 0原文

我正在开发一个项目,其中包含一些比我习惯的稍微复杂的界面元素动态布局。我总是觉得编写复杂的代码来检查某某是否接近某某,并在这种情况下将其向某个方向移动 x% 等等是愚蠢的。这不是编程应该完成的方式。编程应该尽可能是声明性的!

正是因为我要做的事情相当简单,所以我认为这将是尝试新事物的好机会,并且我想到使用 NSPredicate 作为一个简单 < href="http://en.wikipedia.org/wiki/Constraint_satisfaction_problem" rel="nofollow noreferrer">约束求解器。到目前为止,我只使用 NSPredicate 来完成非常简单的任务,但我知道它的功能远不止于此。

这里有什么有用的想法、经验、例子、警告、见解吗?

我将举一个非常简单的例子,以便有一些具体的答案。我如何使用 NSPredicate 来解决以下约束:(

viewB.xmid = (viewB.leftEdge + viewB.width) / 2
viewB.xmid = max(300, viewA.rightEdge + 20 + viewB.width/2)

“viewB 应水平居中于坐标 300,除非其左边缘与 viewB 右边缘的距离不超过 20 像素,在这种情况下,viewA 的左边缘应保持不变”固定在 viewB 右边缘右侧 20 像素处,viewA 的水平中心被推到右侧。”)

viewA.rightEdgeviewB.width 可以变化,这些是“输入变量”。

编辑:任何解决方案可能都必须使用 NSExpression 方法 -(id)expressionValueWithObject:(id)object context:(NSMutableDictionary *)context这个答案是相关的。

I'm working on a project which includes some slightly more complex dynamic layout of interface elements than what I'm used to. I always feel stupid writing complex code that checks if so-and-so is close to such-and-such and in that case move it x% in some direction, etc. That's just not how programming should be done. Programming should be as declarative as possible!

Precisely because what I'm going to do is fairly simple, I thought it would be a good opportunity to try something new, and I thought of using NSPredicate as a simple constraints solver. I've only used NSPredicate for very simple tasks so far, but I know that it capable of much more.

Are there any ideas, experiences, examples, warnings, insights that could be useful here?

I'll give a very simple example so there will be something concrete to answer. How could I use NSPredicate to solve the following constraints:

viewB.xmid = (viewB.leftEdge + viewB.width) / 2
viewB.xmid = max(300, viewA.rightEdge + 20 + viewB.width/2)

("viewB should be horizontally centered on coordinate 300, unless its left edge gets within 20 pixels of viewB's right edge, in which case viewA's left edge should stay fixed at 20 pixels to the right of viewB's right edge and viewA's horizontal center get pushed to the right.")

viewA.rightEdge and viewB.width can vary, and those are the 'input variables'.

EDIT: Any solution would probably have to use the NSExpression method -(id)expressionValueWithObject:(id)object context:(NSMutableDictionary *)context.
This answer is relevant.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Bonjour°[大白 2024-08-30 05:52:59

Cocoa 谓词本质上是 Cocoa 的一种 SQL。它们的大部分功能在于能够进行字符串搜索和比较,并且对于您想要做的事情没有额外的(有用的)设施,即(据我所知)数字比较。我也不认为它们可以生成非常易于维护的代码。

常规布尔表达式在功能上等同于 Cocoa 谓词,您可以重新排列它们并将它们巧妙地分配给一些命名良好的变量。

if (viewAIs20PixelsAway && viewBIs30PixelsAway) {
    [viewA moveToPositionA];
} else ...

(一个非常简单的例子......我可以想出更好的东西。)

另外,你可以将它们隐藏在一个方法中并像使用 NSPredicate 一样评估它们。

Cocoa predicates are essentially a kind of SQL for Cocoa. Most of their power lies in their ability to do string searching and comparisons and have no extra (useful) facilities about what you're trying to do, which is (as far as I can tell) numeric comparisons. I don't think they make for very maintainable code either.

Regular boolean expressions are functionally equivalent to Cocoa predicates, and you can rearrange and assign them cleverly to some nicely-named variables.

if (viewAIs20PixelsAway && viewBIs30PixelsAway) {
    [viewA moveToPositionA];
} else ...

(A very simplistic example... I could've come up with something better.)

Plus, you can tuck them away in a method and evaluate them like you would do with an NSPredicate.

冰魂雪魄 2024-08-30 05:52:59

使用 NSPredicate(和 NSExpression)求解简单的线性方程是一件轻而易举的事,但从那里到求解任意约束集合(又名线性规划)仍然是一大步。最有希望的前进方法是按照 Chris Hanson 建议并更新他的BDRuleEngine。下雨天的有趣项目。

Solving simple linear equations with NSPredicate (and NSExpression) is a breeze, but to go from there to solving arbitrary collections of constraints (aka Linear Programming) is still a big step. The most promising way forward is to do what Chris Hanson suggests and update his BDRuleEngine. Fun project for a rainy day.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文