20190711のSwiftに関する記事は8件です。

【Swift】 UITextFieldの左側に余白を設ける

前置き

今回はほぼ前置きですが。

自作アプリもだいぶイメージができてきて、UITextFieldのplaceHolderにも文字を入れたりして、全体的な見た目を確認したりしてたんですが、どうも文字列が左端ぴったりに設定されて余白が全然ない感じがよろしくない。

↓の画面のようなイメージですね。
Screen Shot 2019-07-11 at 23.30.41.png

左端から少し余白を設けて(要はpadding)、見た目よくしたかったんですが、どうも調べてみるとUITextFieldのカスタムクラスを作って、textRect(forBounds bounds: CGRect)のような関数を設定する、といった手法ばっかりで、おおかた画面イメージも出来てきてるところに今からそんな修正を入れるのも正直面倒。
というわけで、もう少し調べてみると、さらっと解決できる方法がありました。

Screen Shot 2019-07-11 at 23.36.32.png

少し左側に余白ができているのがお分かりいただけると思います。

ソース

実装というより、おまじないのように書いていたある記述が悪さをしていただけ、というハナシなのですが。

ViewController.swift
        textField.borderStyle = .none
        textField.layer.cornerRadius = 5
        textField.layer.masksToBounds = true

UITextFieldの枠線の角に丸みを持たせるために、こういう書き方をしていたのですが、これの一番上の行、textField.borderStryle = .noneという記述があると、textField内の文字列が左にきっちり詰めた状態になるようです。
なので、対処としては、この1行を消してあげるだけです。
(上で画像を貼っているとおり、角の丸みの設定はきちんと残っています)

ViewController.swift
        // textField.borderStyle = .none
        textField.layer.cornerRadius = 5
        textField.layer.masksToBounds = true

もし同様の事象で対処法を探っている方がこれを読まれているのであれば、textField.borderStyle = .roundedRectように明示的に.borderStyleの設定を.none以外に変えてみるのは、対処の一つとして試してみてもよいかもしれません。

まとめ、ポイント

今回は何か新しいやり方を知った・気づいた、というより、「いつもこう書いてるから」という理由で盲目的にソースをコピペして必要な部分だけを書き換えるようなやり方をしていると、実はそのロジックが悪さをしていることに気づきにくい、という教訓を得た感じでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UICollectionView Cell color are confusing

現象

以下のコードのように、土・日曜を赤くしたいですが、reloadData()すると、
赤い字の場所が混乱している。
Simulator Screen Shot - iPhone Xʀ - 2019-07-11 at 22.53.36.png

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let viewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCell",for: indexPath) as! dayCell
        let i = indexPath.row
        if i + 1 < firstWeekday || i + 1 > (daysCount + firstWeekday - 1){
            viewCell.Label.textColor = UIColor.lightGray
        }
        else if i % 7 == 0 || i % 7 == 6 {
            viewCell.Label.textColor = UIColor.red
        }
        return viewCell
    }

原因

UICollectionViewのCellはreusable,なので再生する時使ったCellの属性を残ってしまう。

解決方法

CellのクラスでprepareForReuseメソッドをオーバーライドして毎回Reuse前にデフォルトの設定にする。

import UIKit

class dayCell: UICollectionViewCell {

    @IBOutlet weak var Label: UILabel!
    override func prepareForReuse() {
        super.prepareForReuse()
        Label.textColor = .darkText
    }
}

参考

https://stackoverflow.com/questions/22384992/uicollectionview-reloaddata-changes-cell-order
https://stackoverflow.com/questions/47398944/collectionview-cell-images-are-changing

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【swift】iOSアプリでよく見る『既に開いているタブをタップして、一番上までスクロール』の実装方法

概要

iOSアプリでよく見るこの動きをサクッと実装します

  • tabbarの既に開いているタブアイコンをタップすると、一番上までスクロールする
  • ただしUINavigationControllerでの「戻る遷移」を邪魔しない

アプリの構造

  • タブバー(UITabBarController)が複数の画面(UIViewController)を持っている
  • 各UIViewControllerはUINavigationControllerで遷移する

注意点

UINavigationControllerで遷移する場合、タブをタップ時のデフォルトの動きは
『UINavigationControllerのrootに戻る』であり、
このときはスクロールさせないようにしたい

実装

class SampleTabBarController: UITabBarController, UITabBarControllerDelegate {
    // shouldSelectでは、現在開いている画面がnavigationControllerのルートかを判定するまで。
    var shouldScroll = false
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        self.shouldScroll = false
        // 表示しているvcがnavigationControllerルートのときはスクロールさせる
        // ルート以外は、navigationControllerの戻る機能を優先しスクロールさせない
        if let navigationController: UINavigationController = viewController as? UINavigationController {
            let visibleVC = navigationController.visibleViewController!
            if let index = navigationController.viewControllers.index(of: visibleVC), index == 0 {
                shouldScroll = true
            }
        }
        // 遷移を許可するためのtrueを返す
        return true
    }

    // didSelectで、選択されたタブが、前回と同様なら、shouldSelectの結果(shouldScroll)も考慮し、スクロールさせる
    var lastSelectedIndex = 0
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)  {
        guard self.shouldScroll else { return }

        if self.lastSelectedIndex == tabBarController.selectedIndex  {
            if let navigationController: UINavigationController = viewController as? UINavigationController {

                let visibleVC = navigationController.visibleViewController!
                if let scrollableVC = visibleVC as? ScrollableProtocol {
                    scrollableVC.scrollToTop()
                }

            }
        }
        self.lastSelectedIndex = tabBarController.selectedIndex
    }
}

各タブのViewControllerたちの実装

// スクロールを持つプロトコル
protocol ScrollableProtocol {
    func scrollToTop()
}

// ↑のように protocolで縛ることで、各画面のスクロールが
// scrollViewだろうが、tableViewやcollectionViewだろうが、
// tabbarControllerは意識せずに実行できる

class AAAViewController: ScrollableProtocol {
    // scrollViewを持つViewController
    @IBOutlet weak var scrollView: UIScrollView!
    func scrollToTop() {
        scrollView.setContentOffset(CGPoint(x:0, y:0 - scrollView.contentInset.top), animated: true)
    }
}


class BBBViewController: ScrollableProtocol {
    // tableViewを持つViewController
    @IBOutlet weak var tableView: UITableView!
    func scrollToTop() {
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.scrollToRow(at: indexPath, at: .top, animated: true)
    }
}

class CCCViewController: ScrollableProtocol {
    // collectionViewを持つViewController
    @IBOutlet weak var collectionView: UICollectionView!
    func scrollToTop() {
        let indexPath = IndexPath(row: 0, section: 0)
        collectionView.scrollToItem(at: indexPath, at: .top, animated: true)
    }
}

実装の解説と、改善したいと思っているところ

UINavigationControllerで遷移する場合、タブをタップ時のデフォルトの動きは
『UINavigationControllerのrootに戻る』であり、このときはスクロールさせないようにしたい

この動きがやや面倒で
今回の実装ではTabBarControllerのshouldSelectdidSelectで判定を行っている。

didSelectの発火時では、すでにUINavigationControllerのルートに移動してしまっているため、
UINavigationControllerで遷移先のVCに居たとしても常にスクロールが走ってしまう。

一方でshouldSelectではtabBarController.selectedIndexがまだ
「今回選択されたタブ」ではなく「前回選択されたタブ」であるため
『既に開いているタブが選択された』が判定できない。

この辺をきれいに改善する方法があれば教えてほしいです。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】iOSアプリでよく見る『既に開いているタブをタップして、一番上までスクロール』の実装方法

概要

iOSアプリでよく見るこの動きをサクッと実装します

  • tabbarの既に開いているタブアイコンをタップすると、一番上までスクロールする
  • ただしUINavigationControllerでの「戻る遷移」を邪魔しない

ezgif.com-video-to-gif.gif

アプリの構造

  • タブバー(UITabBarController)が複数の画面(UIViewController)を持っている
  • 各UIViewControllerはUINavigationControllerで遷移する

注意点

概要の通りだが、
UINavigationControllerで遷移する場合、タブをタップ時のデフォルトの動きは
『UINavigationControllerのrootに戻る』であり、
このときはスクロールさせないようにしたい

実装

class SampleTabBarController: UITabBarController, UITabBarControllerDelegate {
    // shouldSelectでは、現在開いている画面がnavigationControllerのルートかを判定するまで。
    var shouldScroll = false
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        self.shouldScroll = false
        // 表示しているvcがnavigationControllerルートのときはスクロールさせる
        // ルート以外は、navigationControllerの戻る機能を優先しスクロールさせない
        if let navigationController: UINavigationController = viewController as? UINavigationController {
            let visibleVC = navigationController.visibleViewController!
            if let index = navigationController.viewControllers.index(of: visibleVC), index == 0 {
                shouldScroll = true
            }
        }
        // 遷移を許可するためのtrueを返す
        return true
    }

    // didSelectで、選択されたタブが、前回と同様なら、shouldSelectの結果(shouldScroll)も考慮し、スクロールさせる
    var lastSelectedIndex = 0
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)  {
        guard self.shouldScroll else { return }

        if self.lastSelectedIndex == tabBarController.selectedIndex  {
            if let navigationController: UINavigationController = viewController as? UINavigationController {

                let visibleVC = navigationController.visibleViewController!
                if let scrollableVC = visibleVC as? ScrollableProtocol {
                    scrollableVC.scrollToTop()
                }

            }
        }
        self.lastSelectedIndex = tabBarController.selectedIndex
    }
}

各タブのViewControllerたちの実装

// スクロールを持つプロトコル
protocol ScrollableProtocol {
    func scrollToTop()
}

// ↑のように protocolで縛ることで、各画面のスクロールが
// scrollViewだろうが、tableViewやcollectionViewだろうが、
// tabbarControllerは意識せずに実行できる

class AAAViewController: ScrollableProtocol {
    // scrollViewを持つViewController
    @IBOutlet weak var scrollView: UIScrollView!
    func scrollToTop() {
        scrollView.setContentOffset(CGPoint(x:0, y:0 - scrollView.contentInset.top), animated: true)
    }
}


class BBBViewController: ScrollableProtocol {
    // tableViewを持つViewController
    @IBOutlet weak var tableView: UITableView!
    func scrollToTop() {
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.scrollToRow(at: indexPath, at: .top, animated: true)
    }
}

class CCCViewController: ScrollableProtocol {
    // collectionViewを持つViewController
    @IBOutlet weak var collectionView: UICollectionView!
    func scrollToTop() {
        let indexPath = IndexPath(row: 0, section: 0)
        collectionView.scrollToItem(at: indexPath, at: .top, animated: true)
    }
}

実装の解説と、改善したいと思っているところ

UINavigationControllerで遷移する場合、タブをタップ時のデフォルトの動きは
『UINavigationControllerのrootに戻る』であり、このときはスクロールさせないようにしたい

この動きがやや面倒で
今回の実装ではTabBarControllerのshouldSelectdidSelectで判定を行っている。

didSelectの発火時では、すでにUINavigationControllerのルートに移動してしまっているため、
UINavigationControllerで遷移先のVCに居たとしても常にスクロールが走ってしまう。

一方でshouldSelectではtabBarController.selectedIndexがまだ
「今回選択されたタブ」ではなく「前回選択されたタブ」であるため
『既に開いているタブが選択された』が判定できない。

この辺をきれいに改善する方法があれば教えてほしいです。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めて開発した個人Toy Project!!

非常に単純な支出管理アプリケーション
Spending Management - SPEM!
旅行,小遣い,その他いろいろのお金を
複雑に管理する必要なく簡単に
目標のタイトルと金額を設定して管理してみてください
皆様の支出をSPEMがお手伝いいたします。

https://apps.apple.com/jp/app/spem/id1470758766

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】ライブラリ Example を Carthage で管理する方法

はじめに

Carthage でライブラリを管理する場合 Cartfile に github "ReactiveX/RxSwift" といった感じで設定を記述すると思います。実は、ここにはローカルリポジトリを指定することも可能です。
この機能を使って scheme を分けて example を作成しているライブラリを Carthage で管理する方法をご紹介します。

この記事は AkkeyLab/RxScreenProtectKit というライブラリを作成・公開するにあたって学んだことをまとめたものになります。

問題

ドキュメント にもある通り git "file:///directory/to/project" "branch" という形式で記述すればいいことがわかります。
しかし、相対パス指定ができません(私の環境・方法では)。

解決策

echo "git \"file://$($(dirname $0); pwd)\"" >> Cartfile

Cartfile の保存場所がライブラリの保存場所と同じ場合、このスクリプトを実行することで、問題を解決できます。やってることとしてはカレントディレクトリの絶対パスを生成して Cartfile に追加しているだけの単純なものです。

git "file:///Users/name/Development/RxScreenProtectKit"

成功例も載せておきます。

おわりに

AkkeyLab/RxScreenProtectKit にも導入しておりますが、 example プロジェクトを動かしたい人用のスクリプトを準備しておくといいかもしれません。ここにも載せておきます。

#!/bin/bash

function command_exists {
  command -v "$1" > /dev/null;
}

echo "git \"file://$($(dirname $0); pwd)\"" >> Cartfile

# carthage
if ! command_exists brew ; then
  /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  brew update
  brew upgrade --all
  brew doctor
  brew -v
fi

if ! command_exists carthage ; then
  brew install carthage
fi

carthage update --platform iOS --no-use-binaries --cache-builds

# SwiftLint
if ! command_exists swiftlint ; then
  brew install swiftlint
fi

追記

Screen Shot 2019-07-12 at 16.27.40.png
実は Embedded Binaries の項目にビルドすることで自動生成される framework ファイルを追加する方法が一般的だと思います。ライブラリ開発時にサンプルを頻繁に使う場合、確実にこのほうが効率的です。この記事は方法の一つとしてご覧ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

githubからcloneした(第3者が製作した)リポジトリを扱う際に詰まった点

xcode

そのままビルドしてもPROJECT側にエラーが出る場合
Automatically manage signingチェックを入れる
SignngTeamのとこは自分のアカウント(または有効なアカウント)に切り替える
IdentityBundle Identifierのところは独自の名前にする(ex. com.hogehoge.アプリ名)

sourceTree,Github

ブランチにチェックアウトしたい時

error: Your local changes to the following files would be overwritten by checkout

と出たら、とりあえずcommitする(pushはしない)

随時書き足します

参考記事

【Git】checkout時に、「error: Your local changes to the following files would be overwritten by checkout: 」|Koushi Kagawa ?|note
git checkout で error: Your local changes to the following files would be overwritten by checkoutと言われる解決方法 - Qiita

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】完全独学で計算機アプリを作成・リリースした話。

はじめに

はじめまして、こなもん@と申します。
プログラミングの学習を始めて約半年の初学者です。

先日、簡単な計算機アプリを独学で作り、App Storeからリリースする事ができました。
SS.png
Heat Calculator

アプリの概要、実際に書いたコード、つまずいた箇所を説明させていただきます。
よろしくお願い致します。

自分のバックグラウンド

Swiftに関してはProgateの講座を2週して、
テキスト「詳細!Swift iPhoneアプリ開発の入門ノート」を半分ほど読んだ程度の知識です。
分からない事はその都度テキストを参照したり、ネット検索をして解決しました。
今回のアプリは、コードを書くのに約3週間、審査まわりに約1週間かけてリリースしました。
審査は1回で通りました。

アプリの概要

薬剤師向け、調剤用の計算機です。
簡単に言うと、÷14と÷21の計算に特化したものです。

薬剤師は処方箋を見て薬を取り揃える際、処方薬の1日量と処方日数を掛け合わせた個数を棚から取り出します。
この際、薬が10錠/1シートの包装のものであれば、計算は楽です。
(ちなみに、薬の包装に使われているプラスチックとアルミでできたシートのことをヒートと言います。以後、ヒートと表記します。)

しかし、医療の現場には14錠/ヒートだったり、21錠/ヒートのものが存在します。
このような1枚に7の倍数の錠剤が包装されたものを、我々はウィークリーヒートと呼びます。業界用語です。
そして、取揃える薬がウィークリーヒートだった場合、計算が少し難しくなります。

例えばですが、次の処方を見てください。

ロキソニン錠60mg 1日3錠
1日3回 毎食後  30日分

この場合、1日3錠x30日分なので、必要な錠剤は90錠です。
10錠/ヒートだと9枚取りそろえればOKですが、
21錠/ヒートだとどうでしょう?

21錠/ヒートx4枚+端数6錠(84+6=90錠)ですね。ちょっとめんどくさいです。

前置きが長くなってしまいました。
このアプリでは左上の入力フォームに①1日量、右上の入力フォームに②処方日数を入力し、
③ウィークリーヒートの種類(14 or 21)を選択する。
この3つの操作だけで、

全量: ① x ② (上記のロキソニンの例だと90錠)
ヒートの枚数: ① x ② / ③の商 (4枚)
端数: ① x ② / ③の端数 (6錠)

上記の3つの計算結果を出してくれます。
既存のものだと、まず全量を求め、そこから再度計算してヒート枚数、端数を求める必要がありました。
3つの操作だけで調剤に必要な計算結果が得られる事が、この計算機の最大の特徴、利点だと思います。

アプリの説明が長くなってしまいました。
簡単にまとめると、

①薬剤師向け
②調剤のややこしい計算を楽にする
③必要な手数を減らした計算機
と、なります。

次からいよいよコーディングに入っていきます。

コードに関して

全体

XCode上のView Controllerの画面です。
スクリーンショット 2019-06-30 2.25.55.png

主な要素は3種類です。
数値を入力するフォームが2つ、押すことで計算をするボタンが2種類、計算結果を表示するラベルが3つあります。

fig1
//コードを記載する場所は以下の【】の数字を参考にしてください。
import UIKit

class ViewController: UIViewController {
    //【①】
    override func viewDidLoad() {
    //【②】
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    //【③】
}

このコード(fig1)は、XCodeのファイルを新規作成した際にすでに記載されている、ViewController.swiftのものです。
コードをどこに記載していくかは、この図を参考にしてください。

フォームに関する設定・説明

まず数値入力用のフォームを2つ作ります、
左上に1日量のText Field(doseField)を、右上に1日量のText Field(daysField)を作成し、Outlet接続します。
XCode上でフォームの中に入力する数値の種類(1日量と日数)を記載しました(Show the Attributes inspectorの画面でPlaceholderに記載)。

//【①】に記載
    @IBOutlet weak var doseField: UITextField!
    @IBOutlet weak var daysField: UITextField!

次に、全量(total)、ヒート枚数(numHeats)、端数(fraction)の計算結果出力用のLabelを作り、Outlet接続します。
画面下部に縦に並べて設置し、その左右にに数値の種類(全量・ヒート枚数・端数)とその単位を記載したLabelを配置させました。

//【①】に記載
    @IBOutlet weak var total: UILabel!
    @IBOutlet weak var numHeats: UILabel!
    @IBOutlet weak var fraction: UILabel!

ボタンに関する設定・説明

最後に、画面中央に÷14の処理をするButtonと÷21の処理をするButtonを作成し、Action接続します。
÷14だけ記しますが、÷21のものもこれと全く同じです(14の部分を21に変えただけです。)

//【①】に記載
//  14を押した時の処理 ①dose x daysで全量 ②ヒート枚数 ③端数
    @IBAction func btn14(_ sender: Any) {

//      【A】テキストフィールドに入力された値を定数化
        let dose:Int? = Int(doseField.text!)
        let days:Int? = Int(daysField.text!)

//      【B】合計への出力 ?? 1 で初期値を1にしている
        let outputTotal = Int((dose ?? 0) * (days ?? 0))
        if outputTotal>5000 {
            total.text = "ERROR"
        }else{
            total.text = String(outputTotal)
        }

//      【C】 ヒート枚数への出力
        let outputnumHeats:Double = Double(((dose ?? 0) * (days ?? 0))/14)
        let outputnumHeatsfloor:Int = Int(floor(outputnumHeats))

        if outputTotal>5000 {
            numHeats.text = "ERROR"
        }else{
            numHeats.text = "14 × " + String(outputnumHeatsfloor)
        }

//      【D】端数への出力
        let outputFraction:Int = Int(((dose ?? 0) * (days ?? 0))%14)
        if outputTotal>5000{
              fraction.text = "ERROR"
        }else{
              fraction.text = String(outputFraction)
        }

//      【E】ボタン押したらキーボード下げる
        view.endEditing(true)
    }

【A】まずTextFieldに入力された値を定数に代入します。
doseFieldに入力されたテキストを定数doseに、
daysFieldに入力されたテキストを定数daysに代入します。
コードとは別に、XCodeの設定で(Show the Attributes Inspector)、Keyboard Type をNumber Padにして、数字のみ入力できるようにしています。

入力された数値を計算式に当てはめ、3種類の計算を行います。

【B】 dose * days
定数doseと定数daysを掛けた値を定数outputTotalに代入します。
その後、計算結果をif文を用いて条件分岐させ、問題なければtotalのLabelに出力させます。

初め、TextFieldに値を入れていない状態でボタンの処理をすると、XCodeが落ちてしまい悩みました。
二つの定数に初期値を設定し(定数 ?? 0 の形で)解決しました。

if文を用いた理由ですが、計算結果が実際の業務において現実的ではない数値(とりあえず>5000としました)だった場合に、エラーである旨を表示したかったからです。
本当は入力する値の範囲を決めることで(1日量は1~12のような感じ)、現実的でない値を除外したかったのですが、分からなかったのでこのような方法を用いて無理やり解決させました。

定数に初期値を与える事と、if文で結果を分岐させる事に関しては、以下の2つの計算においても同じです。

【C】 (dose * days) ÷ 14の商
上記の計算式を、まずDoubleの形で定数outputnumHeatsに代入します。
その後、outputnumHeatsをfloor()で整数にし、Int型のoutputnumHeatsfloorに代入します。
if文を用い、numHeatsのLabelに出力します。
ボタンを押した後に、14と21どちらのボタンかわかりやすいように、"14 x "のテキストも添えて出力させています。

【A】 (dose * days) ÷ 14の端数
(dose * days) % 14で端数を求め、Int型の定数outputFractionに代入します。
その後if文を用い、問題なければfractionのLabelにoutputFractionの値を出力します。

【E】最後に、14・21ボタンを押したあと、計算結果が見えやすいようにキーボードを下げるコードも入れました。

計算の機能に関するコードは以上です。
...ちなみに作成後に思いついたのですが、if文を以下のように記述すればよりスッキリ書けたと思いました。

        if outputTotal>5000 {
            total.text = "ERROR"
            numHeats.text = "ERROR"
            fraction.text = "ERROR"
        }else{
            total.text = String(outputTotal)
            numHeats.text = "14 × " + String(outputnumHeatsfloor)
            fraction.text = String(outputFraction)
        }

デザインに関する設定・説明

次に、ボタンやラベルに色などのデザイン要素を設定します。
デザイン用に、ボタン2つとラベル3つを再度Outlet接続しました。

//  【①】に記載
    @IBOutlet weak var btn14: UIButton!
    @IBOutlet weak var btn21: UIButton!

    @IBOutlet weak var totalLabel: UILabel!
    @IBOutlet weak var numHeatsLabel: UILabel!
    @IBOutlet weak var fractionLabel: UILabel!

次に、ボタンやラベル、背景の色、ラベルの形を設定します。

//      【②】に記載

        //色の設定
        let bgcolor = UIColor(red: 180/255, green: 214/255, blue: 211/255, alpha: 1.0)
        let btncolor1 = UIColor(red: 135/255, green: 179/255, blue: 141/255, alpha: 1.0)
        let btncolor2 = UIColor(red: 48/255, green: 197/255, blue: 255/255, alpha: 1.0)

        // 背景の色
        view.backgroundColor = bgcolor

        // btnの色
        btn14.backgroundColor = btncolor1
        btn14.setTitleColor(UIColor.white, for: .normal)
        btn21.backgroundColor = btncolor2
        btn21.setTitleColor(UIColor.white, for: .normal)

        // ラベル枠を丸くする
        totalLabel.layer.masksToBounds = true
        // ラベル丸枠の半径
        totalLabel.layer.cornerRadius = 10

        numHeatsLabel.layer.masksToBounds = true
        numHeatsLabel.layer.cornerRadius = 10

        fractionLabel.layer.masksToBounds = true
        fractionLabel.layer.cornerRadius = 10

まず、色をRGBAで指定し、定数に代入しました。
Swiftでは○○○/255といった感じでRGBを指定するようです。(少しつまづきました)

上記の色の定数を、.backgroundColorで背景とボタン2つに代入しました。
ボタン内の文字色(白色)は.setTitleColorで設定しました。
(ここの色もRGBAで指定して代入しようとしたのですがうまくいかず、上記のコードを使用しました。)

最後に、ラベルの枠の丸さを設定しています。

その他コード

Tap Gesture Recognizerを接続し、以下のコードを加える事で、
画面をタップした時にキーボードを引っ込めることができます。

   //【③】に記載
   @IBAction func tapView(_ sender: UITapGestureRecognizer) {
        view.endEditing(true)
    }

以上がViewController.swiftに記載したコードの全てです。
他にもXCode上でレスポンシブデザインの要素をいじったりしていますが、その辺りはこの記事では省略させていただきます。

参考記事

最後に、審査関係などプログラミング以外で役に立ったブログやサイトを紹介します。

アプリの登録・申請・リリースまでの流れについて、この記事を参考にしました。とても分かりやすかったです。
https://i-app-tec.com/ios/app-release.html

アプリをリリースする際に、アイコンを作成し、登録する必要があります。
以下の記事を参考にして、アイコンを自作しました。
https://qiita.com/seihmd/items/25f2a42e20e88ea5d86f

アプリをApple Developer Programに登録する際、画面のスクショを登録する必要があるのですが、サイズが合わず弾かれて困っていました。
以下のサイトで、画像のサイズを指定、変換して用いました。
https://www.peko-step.com/

最後に

これでこの記事は終わりです。

まだプログラミングに関しても、Qiitaの投稿に関しても初心者ですので、至らない点が多いかと思います。
何か気づきがありましたら、アドバイスいただけると幸いです。

最後まで読んでいただき、ありがとうございました。

以上です。ではまた!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む