4

私のアプリの機能の 1 つは、画像の自動トリミングを行うものです。

基本的なアイデアは、誰かが一枚の紙 (レシートと考えてください) の写真を撮り、紙の境界が決定された後、画像が自動的にトリミングされるというものです。

OpenCV を使用して、紙の境界線を特定できます。したがって、次に行うことは、各ガイドの「中心」プロパティを変更することです (手動でドラッグできる水平 2 本と垂直 2 本の「線」のみ)。

次に、4 つのガイドのそれぞれを変更するためにすべての呼び出しを行った直後に、別の何かがやってきて、再び「中心」を設定します。(これを証明するために「setCenter」をオーバーライドしました)。中心はこれによってリセットされるようです: [UIView(Geometry) _applyISEngineLayoutValues]

なぜこれが起こっているのか、またはそれを止める方法はわかりませんが、おそらく制約に関係しています。私のビューは単純な UIButton です。ユーザーが指でタップしてドラッグすると、中心を変更するだけのアクション ルーチンが呼び出されます。これは機能します。

しかし別のケースでは、UIImagePickerController を立ち上げています。彼らが画像を選択した後、用紙の境界を決定し、「ガイド」の中心を変更し、後で「_applyISEngineLayoutValues」でそれらをすべて元に戻します。

この場合、何が起こっているのか分かりますか? または、どのようにビューの中心を設定し、実際にそのままにすることができますか?

4

2 に答える 2

12

frameAutoLayout の最初のルールは、ビューのboundsまたはcenterを直接更新できないことです。

制約によってビューが更新されるように、ビューに関連する制約を更新する必要があります。

たとえば、最初の垂直線には、次のような水平方向の制約があります...

1. Leading edge to superview = some value.
2. Width = some value.

これは、この行を画面に (水平に) 配置するのに十分です。

さて、この行を右に移動したい場合は、これを行う必要があるだけでは変更できませcenterん...

1. Create a property in you view controller like this...

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *verticalLine1LeadingConstraint;
// or if you're coding the constraint...
@property (nonatomic, strong) NSLayoutConstraint *verticalLine1LeadingConstraint;

2. Save the constraint in to that property...

// either use IB to CTRL drag the constraint to the property like any other outlet.
// or something like...

self.verticalLine1LeadingConstraint = [NSLayotuConstraint ... // this is the code adding the constraint...

[self.view addConstraint:self.verticalLine1LeadingConstraint];

これで、この制約を指すプロパティができました。

ここで、垂直線 1 の「中心を更新」する必要がある場合は...

// Calculate the distance you want the line to be from the edge of the superview and set it on to the constraint...

float distanceFromEdgeOfSuperview = // some calculated value...

self.verticalLine1LeadingConstraint.constant = distanceFromEdgeOfSuperview;

[self.view layoutIfNeeded];

これにより、ビューの位置が更新され、エラーは発生しません。

于 2013-07-17T08:12:12.930 に答える
3

あなたは自動レイアウトを使用しているので、フォグマイスターの答えは正しいものですが、誰もが自動レイアウトを使用できるわけではありません-たとえば、iPad 1をサポートする必要がある人-この回答をここに残します.

ビューのフレームを使用する必要があるが、システムが制約を追加している場合は、回避策があります。しかし、それはきれいではありません。

_applyISEngineLayoutValuesビューのcenterと を設定しますboundsが、 には触れませんframesetCenter:andをオーバーライドsetBounds:して何もせず、常にsetFrame:独自のコードで使用すると、その_applyISEngineLayoutValuesままになります。

私はこのアプローチに満足していませんが、これまでのところ_applyISEngineLayoutValues、レイアウト ロジック全体にうんざりするのを止める唯一の方法です。

于 2013-07-17T07:49:45.413 に答える