読み込み中...

Swiftで絶対座標をマスターするたったの10方法

Swiftの絶対座標を学ぶイラスト Swift
この記事は約26分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

SwiftはAppleが開発したプログラミング言語であり、iOSやmacOS、watchOS、tvOSのアプリ開発に使用されます。

Swiftにおいて、UIの配置やアニメーション、タッチイベントの取得など多くの操作で「座標」がキーポイントとなります。

特に「絶対座標」の理解は、高度なUI操作やアニメーションを行う上で不可欠です。

この記事を読めば、Swiftで絶対座標を利用したプログラミングができるようになります。

具体的な使い方から応用例、さらには注意点やカスタマイズ方法まで、絶対座標を利用した開発の全体像を掴むことができるでしょう。

●Swiftと絶対座標とは

Swiftは、CやObjective-Cに比べて文法がシンプルで読みやすく、また実行速度も高速です。

そのため、初心者からプロの開発者まで幅広く利用されています。

○Swiftの基本的な概要

Swiftでは、様々なUIコンポーネントを配置する際、その位置を指定するために座標が必要となります。

座標は通常、x軸とy軸の2つの値で表され、これを使って画面上の位置を特定します。

○絶対座標の意味と重要性

絶対座標とは、画面やウィンドウの左上を(0,0)としたときの、その点からの距離を示す座標のことを指します。

他にも「相対座標」という言葉がありますが、これはある参照点を基準にした座標を指します。

例えば、あるビューの中心を基準にした座標などがそれに該当します。

SwiftでのUI開発において、特定の位置にコンポーネントを配置する、あるいはユーザーのタッチ位置を取得する際に、この絶対座標がどのように計算されるかを理解することは非常に重要です。

このコードでは絶対座標を使ってビューの位置を指定しています。

この例ではUIViewのframeを指定して、画面上の(50,100)の位置にビューを配置しています。

let view = UIView()
view.frame = CGRect(x: 50, y: 100, width: 100, height: 100)
view.backgroundColor = .blue
self.view.addSubview(view)

実行すると、画面上に青色の正方形のビューが表示されることが確認できます。

このように絶対座標を利用することで、具体的な位置にUIコンポーネントを配置することができるのです。

●Swiftで絶対座標を使用する方法

Swiftのアプリ開発では、各UI要素の配置やアニメーションを実現するために座標系を頻繁に使用します。

特に、絶対座標を使いこなせるかどうかで、アプリの品質や使いやすさが大きく左右されます。

ここでは、Swiftで絶対座標を上手く活用するための基本的な方法やコツについて、具体的なサンプルコードを交えて解説します。

○サンプルコード1:基本的な絶対座標の取得

UIViewやそのサブクラスにはframeプロパティが存在し、これを使ってビューの絶対座標やサイズを取得することができます。

let button = UIButton(frame: CGRect(x: 30, y: 50, width: 120, height: 40))
self.view.addSubview(button)

let buttonPosition = button.frame.origin
print("ボタンの絶対座標: \(buttonPosition)")

このコードでは、画面の(30,50)の位置にUIButtonを配置しています。

また、ボタンの絶対座標を取得してコンソールに出力しています。

実行すると、ボタンの絶対座標: (30.0, 50.0)というメッセージがコンソールに表示されます。

○サンプルコード2:UIViewの位置を絶対座標で設定

UIViewの位置を変更する場合、frameプロパティを直接変更することで絶対座標での位置指定が可能です。

let myView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
myView.backgroundColor = .green
self.view.addSubview(myView)

// 絶対座標を(100,200)に変更
myView.frame.origin = CGPoint(x: 100, y: 200)

このコードでは、初めに(0,0)の位置に緑色のUIViewを配置しています。

その後、その位置を(100,200)に変更しています。

実行すると、画面上に緑色のUIViewが(100,200)の位置に表示されることが確認できます。

○サンプルコード3:タッチイベント時の絶対座標の取得

アプリのインターフェースにおいて、ユーザーのタッチイベントは最も基本的なインタラクションの一つです。

その際、タッチされた座標を正確に取得することが求められます。

ここでは、Swiftでタッチイベント時の絶対座標を取得する方法について詳しく見ていきましょう。

UIViewControllerをサブクラス化して、touchesBeganメソッドをオーバーライドすることで、タッチされたポイントを取得することができます。

import UIKit

class TouchViewController: UIViewController {

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let position = touch.location(in: self.view)
            print("タッチされた座標: \(position.x), \(position.y)")
        }
    }
}

このコードでは、タッチイベントが発生した際に、その座標を取得し、コンソールに表示しています。

アプリを実行して、画面をタッチすると、たとえば「タッチされた座標: 150.0, 220.0」というようにタッチした場所のx座標とy座標がコンソールに表示されます。

○サンプルコード4:スクロールビュー内の絶対座標の計算

UIScrollViewやUITableViewなどのスクロール可能なビュー内での絶対座標の取得は、少し工夫が必要です。

contentOffsetを考慮することで、正確な絶対座標を算出することができます。

下記のサンプルコードでは、UIScrollView内の特定の位置をタッチした際の絶対座標を計算します。

import UIKit

class ScrollViewController: UIViewController {

    let scrollView = UIScrollView()

    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView.frame = self.view.bounds
        scrollView.contentSize = CGSize(width: 1000, height: 1000)
        self.view.addSubview(scrollView)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let positionInView = touch.location(in: scrollView)
            let absolutePosition = CGPoint(x: positionInView.x + scrollView.contentOffset.x, y: positionInView.y + scrollView.contentOffset.y)
            print("絶対座標: \(absolutePosition.x), \(absolutePosition.y)")
        }
    }
}

このコードでは、UIScrollViewのcontentOffsetを用いて、スクロールされた分を考慮した絶対座標を計算しています。

UIScrollViewをスクロールしてから、特定の位置をタッチすると、スクロールされた分を含めた絶対座標がコンソールに表示されます。

たとえば、300px下にスクロールして、(50,50)の位置をタッチした場合、「絶対座標: 50.0, 350.0」と表示されます。

○サンプルコード5:アニメーションと絶対座標の連携

Swiftでのアニメーションは、絶対座標との連携が非常に重要です。

UIView.animateメソッドを使用して、絶対座標を変更することで、滑らかなアニメーションを実現することができます。

下記のサンプルコードは、ボタンをタッチすると、UIViewが指定した絶対座標へアニメーションしながら移動する例です。

import UIKit

class AnimationViewController: UIViewController {

    let animateView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        animateView.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
        animateView.backgroundColor = .blue
        self.view.addSubview(animateView)

        let button = UIButton(frame: CGRect(x: 50, y: 200, width: 100, height: 50))
        button.setTitle("移動", for: .normal)
        button.addTarget(self, action: #selector(moveView), for: .touchUpInside)
        self.view.addSubview(button)
    }

    @objc func moveView() {
        UIView.animate(withDuration: 0.5) {
            self.animateView.frame.origin = CGPoint(x: 150, y: 150)
        }
    }
}

このコードでは、ボタンをタッチすると、青いUIViewが(150,150)の絶対座標へ0.5秒かけて移動します。

ボタンをタッチすると、UIViewが指定した絶対座標へスムーズに移動するアニメーションが再生されることが確認できます。

●Swiftでの絶対座標の応用例

Swiftにおける絶対座標の知識を基に、具体的な応用例としてどのように活用できるのかを掘り下げてみましょう。

絶対座標を駆使することで、ユーザーインターフェースの豊かな表現や効果的な動作が可能になります。

○サンプルコード6:絶対座標を利用したドラッグ&ドロップ機能

ドラッグ&ドロップは、アプリ内でオブジェクトを動かす直感的な方法として広く利用されています。

下記のサンプルコードは、UIViewをドラッグして移動する際の絶対座標の取得と利用方法を表しています。

import UIKit

class DragDropViewController: UIViewController {

    var draggableObject: UIView!
    var lastLocation = CGPoint(x: 0, y: 0)

    override func viewDidLoad() {
        super.viewDidLoad()

        draggableObject = UIView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
        draggableObject.backgroundColor = .green
        self.view.addSubview(draggableObject)

        let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(detectPan))
        draggableObject.isUserInteractionEnabled = true
        draggableObject.addGestureRecognizer(panRecognizer)
    }

    @objc func detectPan(recognizer: UIPanGestureRecognizer) {
        let translation = recognizer.translation(in: self.view)
        if let view = recognizer.view {
            view.center = CGPoint(x: lastLocation.x + translation.x, y: lastLocation.y + translation.y)
        }
        if recognizer.state == .ended {
            lastLocation = draggableObject.center
        }
    }
}

このコードでは、UIPanGestureRecognizerを使ってUIViewのドラッグアクションを検知し、その移動量を絶対座標に変換してドラッグ&ドロップを実現しています。

アプリを起動して、緑のUIViewをドラッグすると、指定した位置に応じてスムーズに移動します。

○サンプルコード7:絶対座標を使ったカスタムビューの作成

絶対座標の知識を活用することで、カスタムビューの作成も容易になります。

ここでは、絶対座標を使用してカスタムの円形ビューを中心に配置する例を紹介します。

import UIKit

class CustomViewViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let customView = CircularView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        customView.center = self.view.center
        self.view.addSubview(customView)
    }
}

class CircularView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.layer.cornerRadius = frame.size.width / 2
        self.backgroundColor = .red
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

このコードでは、UIViewをサブクラス化して、その中心を画面の中心の絶対座標に設定することで、カスタムの円形ビューを作成しています。

アプリを起動すると、赤い円形のカスタムビューが画面の中央に正確に配置されていることが確認できます。

このように、絶対座標を利用することで、カスタムビューを自由に配置したり、デザインを施すことができます。

○サンプルコード8:絶対座標に基づくヒットテスト

Swiftのヒットテストは、特定の座標に対応するビュー要素を特定するための技術です。

これにより、ユーザーがタッチした場所にあるビュー要素を瞬時に判定することができます。

絶対座標と組み合わせることで、アプリ内の任意の位置に対するヒットテストの実行が可能となります。

下記のサンプルコードでは、絶対座標に基づくヒットテストの方法を表しています。

import UIKit

class HitTestViewController: UIViewController {

    let testView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        testView.frame = CGRect(x: 50, y: 50, width: 200, height: 200)
        testView.backgroundColor = .blue
        view.addSubview(testView)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        view.addGestureRecognizer(tapGesture)
    }

    @objc func handleTap(gesture: UITapGestureRecognizer) {
        let touchPoint = gesture.location(in: view)
        if let hitView = view.hitTest(touchPoint, with: nil) {
            print("ヒットテストの結果: \(hitView)")
        }
    }
}

このコードでは、UITapGestureRecognizerを用いてタッチイベントを検知します。

そして、handleTapメソッド内でhitTest(_:with:)メソッドを使用して、タッチされた絶対座標に存在するビュー要素を取得しています。

アプリを起動し、青い四角の範囲内と範囲外の2つの場所をタップすると、ヒットテストの結果が異なることが確認できます。

青い四角内をタップすると、testViewがヒットとして検出され、それ以外の場所をタップすると、背景のviewが検出される結果となります。

○サンプルコード9:ゲームやアートワークでの絶対座標の活用

ゲームやアートワークアプリケーションでは、ユーザーのタッチ位置に応じて様々な動きやエフェクトを実行することが多いです。

このような場面でも、絶対座標の知識は非常に役立ちます。

例えば、下記のサンプルコードは、ユーザーがタッチした位置に円を描画するアートワークアプリケーションの一部を表しています。

import UIKit

class ArtworkViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        view.addGestureRecognizer(tapGesture)
    }

    @objc func handleTap(gesture: UITapGestureRecognizer) {
        let touchPoint = gesture.location(in: view)
        drawCircle(at: touchPoint)
    }

    func drawCircle(at point: CGPoint) {
        let radius: CGFloat = 50.0
        let circle = UIView(frame: CGRect(x: point.x - radius, y: point.y - radius, width: radius * 2, height: radius * 2))
        circle.backgroundColor = .random()
        circle.layer.cornerRadius = radius
        view.addSubview(circle)
    }
}

このコードでは、タッチされた絶対座標を基に、その位置に円を描画しています。

円の中心としてタッチ位置を使用し、指定された半径でUIViewを作成して画面上に表示しています。

アプリを起動して、画面の任意の位置をタッチすると、タッチした場所に色の異なる円が次々と描画される様子が観察できます。

これにより、絶対座標の活用がどのようにゲームやアートワークアプリケーションで役立つのか、具体的なイメージを持つことができます。

○サンプルコード10:絶対座標を利用した複雑なレイアウトの制御

絶対座標は、複雑なレイアウトやアニメーションの制御にも役立ちます。

下記のサンプルコードは、絶対座標を使用して複数のビュー要素を動的に配置する方法を表しています。

import UIKit

class LayoutViewController: UIViewController {

    let elements = [UIView(), UIView(), UIView()]

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        for (index, element) in elements.enumerated() {
            element.frame = CGRect(x: 20, y: 100 + CGFloat(index) * 60, width: 50, height: 50)
            element.backgroundColor = .random()
            view.addSubview(element)
        }
    }
}

このコードでは、絶対座標を用いて3つのビュー要素を垂直に均等に配置しています。

ビュー要素のインデックスに応じてy座標を動的に計算することで、ビュー要素間の間隔を一定に保っています。

アプリを起動すると、画面上に色の異なる3つの四角が均等な間隔で表示されます。

このように、絶対座標を活用することで、複雑なレイアウトやアニメーションの制御もスムーズに行うことができます。

●絶対座標の注意点と対処法

Swiftでの絶対座標を使用する際、その利点を最大限に生かすためにはいくつかの注意点と対処法を理解しておくことが重要です。

ここでは、絶対座標を使用する際の主な注意点とそれに対する対処法について詳しく解説していきます。

○端末間の座標差異への対応

異なるiOSデバイスは、異なるスクリーンサイズと解像度を持っています。

このため、絶対座標を用いたレイアウトや配置は、端末間で異なる表示結果となる可能性があります。

特に、iPadとiPhoneなど、大きく異なるデバイス間での違いは顕著になりやすいです。

この問題への対処法として、下記のサンプルコードでは、デバイスのスクリーンサイズを取得し、それに基づいて絶対座標を動的に計算する方法を表しています。

import UIKit

class AdaptiveLayoutViewController: UIViewController {

    let box = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        let screenSize = UIScreen.main.bounds.size
        let boxSize: CGFloat = 100

        // スクリーンの中央に配置
        let x = (screenSize.width - boxSize) / 2
        let y = (screenSize.height - boxSize) / 2
        box.frame = CGRect(x: x, y: y, width: boxSize, height: boxSize)
        box.backgroundColor = .red

        view.addSubview(box)
    }
}

このコードでは、デバイスのスクリーンサイズを取得し、そのサイズに基づいて赤い四角を中央に配置しています。

これにより、異なるデバイスでも中央に赤い四角が表示されることが確認できます。

○絶対座標と相対座標の混同を避ける方法

絶対座標は、スクリーン上の固定的な位置を表すものです。

一方、相対座標は、あるビューを基準としてその内部の位置を表すものです。

これら二つを混同すると、意図しないレイアウトや挙動が生じる可能性があります。

下記のサンプルコードでは、親ビュー内に子ビューを配置し、その子ビューの内部でさらに別のビューを相対座標を用いて配置する方法を表しています。

import UIKit

class CoordinateViewController: UIViewController {

    let parentView = UIView()
    let childView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        parentView.frame = CGRect(x: 50, y: 50, width: 200, height: 200)
        parentView.backgroundColor = .gray
        view.addSubview(parentView)

        childView.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
        childView.backgroundColor = .green
        parentView.addSubview(childView)
    }
}

この例では、childViewの座標はparentViewの左上を基準として設定されています。

したがって、childViewparentViewの内部で(50, 50)の位置に配置されます。

絶対座標と相対座標を正しく使い分けることで、複雑なレイアウトやネストされたビューの関係もスムーズに表現することができます。

●絶対座標のカスタマイズ方法

Swiftでの絶対座標を使用する際、その座標をカスタマイズすることでさまざまな効果や表現を実現することができます。

ここでは、Swiftで絶対座標のカスタマイズ方法を詳しく解説し、それを活用した応用例やヒントを提供します。

○カスタムビューの作成時のヒント

絶対座標を活用したカスタムビューを作成する際の基本的なヒントを紹介します。

□サイズの動的変更

絶対座標を用いることで、ビューのサイズを動的に変更することができます。

これにより、アニメーションなどでビューの大きさを変化させる際の位置調整が容易になります。

このコードでは、UIViewのサイズを動的に変更しています。

この例では、UIViewの幅を200から250に変更し、その中心位置を維持したまま大きさを変えています。

import UIKit

class CustomViewController: UIViewController {

    let customView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        customView.frame = CGRect(x: 60, y: 60, width: 200, height: 200)
        customView.backgroundColor = .blue
        view.addSubview(customView)

        // サイズを変更
        let newSize = CGSize(width: 250, height: 250)
        customView.bounds.size = newSize
    }
}

□回転や拡大

CGAffineTransformを用いることで、絶対座標を基準にした回転や拡大縮小のアニメーションを実装できます。

下記のサンプルコードでは、UIViewを45度回転させています。

import UIKit

class RotationViewController: UIViewController {

    let rotateView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        rotateView.frame = CGRect(x: 80, y: 80, width: 150, height: 150)
        rotateView.backgroundColor = .orange
        view.addSubview(rotateView)

        // 45度回転
        rotateView.transform = CGAffineTransform(rotationAngle: .pi / 4)
    }
}

○サードパーティライブラリの活用

Swiftでの絶対座標のカスタマイズを更に拡張するために、サードパーティライブラリを活用することができます。

例えば、SnapKitやMasonryなどのライブラリを利用することで、絶対座標の設定をより簡単かつ直感的に行うことができます。

下記のサンプルコードは、SnapKitを用いてUIViewのレイアウトを設定しています。この例では、ビューを画面中央に配置しています。

import UIKit
import SnapKit

class SnapKitViewController: UIViewController {

    let centerView = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        centerView.backgroundColor = .green
        view.addSubview(centerView)

        centerView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(100)
        }
    }
}

このように、絶対座標のカスタマイズは、Swiftの基本的な機能だけでなく、サードパーティライブラリを活用することで、さまざまな表現や効果を容易に実現することができます。

まとめ

Swiftでの絶対座標の取り扱いについての探索は、アプリケーション開発において非常に重要なテーマとなります。

この記事では、絶対座標の基本的な概念から応用的な使用方法、そしてカスタマイズの手法に至るまで、幅広く詳細に解説を行いました。

まず、Swiftの基本的な概要と絶対座標の意味・重要性について触れました。

絶対座標を用いることで、アプリ内でのUI要素の位置や動きを正確に制御することができるため、ユーザー体験の向上に直結します。

次に、絶対座標の基本的な取得方法やUIViewの位置設定、アニメーションとの連携など、具体的な実装方法について深く探求しました。

サンプルコードを交えての解説を通じて、初心者から上級者までが絶対座標の活用方法を理解し、技術を磨くことができる内容となっています。

また、絶対座標の応用例やカスタマイズ方法についても細かく説明しました。

特に、サードパーティライブラリを活用することで、更に高度なカスタマイズや表現が可能となることを解説しました。

最後に、絶対座標を使用する際の注意点や端末間の座標差異への対応方法、相対座標との混同を避ける方法など、実践的なアドバイスを交えて解説しました。

Swiftでの絶対座標をマスターすることは、アプリケーション開発の質を向上させるだけでなく、デザイナーや他の開発者との連携もスムーズにする要素となります。

この記事を参考に、Swiftでの絶対座標の取り扱いに自信を持ち、更なるアプリ開発の成功を追求してください。