ios - 書き方 - swift 座標




Swift な数値とCGFloat(CGPoint、CGRectなど) (2)

実生活で頻繁に起こるように、CGRectやCGPointに関して、私はココアタッチとコミュニケーションを取らなければなりません(例えば、何かのframeboundsについて話しているので)。

CGFloat対Double

UIViewControllerサブクラスの無害な次のコードを検討してください。

let scale = 2.0
let r = self.view.bounds
var r2 = CGRect()
r2.size.width = r.size.width * scale

このコードはコンパイルに失敗し、最後の行では通常の不思議なエラーが表示されます。

指定された引数を受け入れる '*'のオーバーロードを見つけることができませんでした

このエラーは、あなたが今までに知っているように、タイプ間のインピーダンスのミスマッチがあることを示しています。 r.size.widthとして到着します。これはSwift Floatと自動的に交換されますが、Swift Double変数とは相互運用できません(デフォルトではscaleと同じです)。

この例は人為的に簡潔であるため、人工的に簡単な解決策があります。これは、行程からフロートにscaleをキャストすることです。 しかし、その場全体から引き出された多くの変数が、提案されたCGRectの要素の計算に関与している場合、多くのキャストが必要です。

冗長イニシャライザ

もう一つの不安は、新しいCGRectを作成するときに何が起こるかです。 ドキュメントにもかかわらず、値の付いた初期化子はありませんが、ラベルはありません。 これはDoublesがあるのでコンパイルに失敗します:

let d = 2.0
var r3 = CGRect(d, d, d, d)

しかし、たとえフロートにdをキャストしても、コンパイルはしません。

コール中の引数ラベル 'x:y:width:height:'がありません

だから私たちはCGRectMake 、これはObjective-Cの改良ではありません。 そして時にはCGRectMakeとCGSizeMakeは改良されていません。 私のアプリから実際のコードを考えてみましょう:

let kSEP : Float = 2.0
let intercellSpacing = CGSizeMake(kSEP, kSEP);

私のプロジェクトの1つでは、それは機能します。 別の方法では、それは不思議なことに失敗します - まったく同じコード! - このエラー:

'NSNumber'は 'CGFloat'のサブタイプではありません

SwiftはFloatをNSNumberにキャスティングすることで "ブリッジを越えようとする"ようなことがありますが、ブリッジの反対側のものがCGFloatを期待しているときには間違ったことです。 私はまだ、2つのプロジェクトの間にエラーが1つではなく他の人に(おそらく他の誰かに)表示されるという違いが何であるかを理解していません。

注:私はその問題を把握しているかもしれません。それはビルドアクティブアーキテクチャのみのビルド設定に依存しているようですが、これは64ビット問題であることを示唆しています。 これは、Floatは64ビットデバイス上のCGFloatと一致しないため、意味があります。 つまり、インピーダンスのミスマッチの問題は私が思っていたよりも悪いことです。

結論

私はこのトピックに関する知恵の実用的な言葉を探しています。 私は誰かがCGRectとCGPoint拡張を考案して、人生をもっと楽にするかもしれないと考えています。 (あるいは可能であれば、CGFloatとIntまたはDoubleを "ちょうどうまく動作する"ような追加の算術演算子関数のオーバーロードが発生している可能性があります)。


DoubleとIntの拡張を作成して、計算されたCGFloatValueプロパティを追加しました。

extension Double {
    var CGFloatValue: CGFloat {
        get {
            return CGFloat(self)
        }
    }
}
extension Int {
    var CGFloatValue: CGFloat {
        get {
            return CGFloat(self)
        }
    }
}

let someCGFloat = someDoubleOrInt.CGFloatValueを使用してアクセスします。

また、あなたのCGRect Initializerに関しては、ラベルを残しているので、欠けている引数のラベルエラーを取得します。あなたはラベルを残すことができないCGRect(x: d, y: d, width: d, height: d)引数が1つしかない場合を除きます。


あなたが発見したように、 CGFloat明示的に型を入力することは、本当に迅速な入力問題を処理する方法です。 その他の参考資料:

let scale: CGFloat = 2.0
let r = self.view.bounds
var r2 = CGRect()
r2.size.width = r.width * scale

2番目の質問に答える方法がわからない場合は、別のタイトルで別に投稿することができます。

更新:

スウィフトクリエイターとリードの開発者Chris Lattnerは、2014年7月4日にApple Developer Forumでこの問題についてこれを述べました。

ここで起こっていることは、CGFloatが、32ビットまたは64ビットのどちらをビルドしているかによって、FloatまたはDoubleのいずれかのタイプアリアであることです。 これはObjective-Cの動作とまったく同じですが、Swiftでは暗黙的な変換が許可されていないため、Swiftでは問題があります。

私たちはこの問題を認識しており、深刻であると考えています。現在、いくつかの異なるソリューションを評価しており、後のベータ版でこれを公開します。 あなたが気づくように、今日Doubleにキャストすることでこれに対処することができます。 これは控えめですが効果的です:-)

Xcode 6 Beta 5のアップデート:

CGFloatは任意の整数型(大きさの整数型を含む)から構築することができ、その逆も可能です。 (17670817)





swift