Swift4 PagingMenuControllerでタブを実装する

PagingMenuControllerとは

上部のタブをスワイプで切り替えることが出来るUIライブラリ

f:id:taillook:20171020191014g:plain

インストール

今回はCocoaPodsでインストールします.

# Uncomment the next line to define a global platform for your project
platform :ios, '11.0'

target 'test' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for test
  pod 'PagingMenuController'
end

実装

まず,Storyboard上でViewController(以下vc)を3つ置く.
次に各ViewControllerにclassを設定する.

  • 白背景のvcにViewController
  • 緑背景のvcにViewController1
  • ピンク背景のvcにViewController2

f:id:taillook:20171020191419p:plain

以下コード
ViewController.swift

import UIKit
import PagingMenuController

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let options = PagingMenuOptions()
        let pagingMenuController = PagingMenuController(options: options)
        
        addChildViewController(pagingMenuController)
        view.addSubview(pagingMenuController.view)
        pagingMenuController.didMove(toParentViewController: self)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

private struct PagingMenuOptions: PagingMenuControllerCustomizable {
    let vc1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController1") as! ViewController1
    let vc2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
    
    fileprivate var componentType: ComponentType {
        return .all(menuOptions: MenuOptions(), pagingControllers: pagingControllers)
    }
    
    fileprivate var pagingControllers: [UIViewController] {
        return [vc1, vc2]
    }
    
    fileprivate struct MenuOptions: MenuViewCustomizable {
        var displayMode: MenuDisplayMode {
            return .segmentedControl
        }
        var height: CGFloat {
            return 40
        }
        var backgroundColor: UIColor {
            return UIColor.gray
        }
        var selectedBackgroundColor: UIColor {
            return UIColor.gray
        }
        var focusMode: MenuFocusMode {
            return .underline(height: 4, color: UIColor.darkGray, horizontalPadding: 0, verticalPadding: 0)
        }
        var itemsOptions: [MenuItemViewCustomizable] {
            return [MenuItem1(), MenuItem2()]
        }
    }
    
    fileprivate struct MenuItem1: MenuItemViewCustomizable {
        var displayMode: MenuItemDisplayMode {
            return .text(title: MenuItemText(text: "First", color: UIColor.lightGray, selectedColor: UIColor.white))
        }
    }
    
    fileprivate struct MenuItem2: MenuItemViewCustomizable {
        var displayMode: MenuItemDisplayMode {
            return .text(title: MenuItemText(text: "Second", color: UIColor.lightGray, selectedColor: UIColor.white))
        }
    }
}

PagingMenuOptionsのMenuOptions内でビューのUIをカスタマイズしている.

TableViewのHeaderとFooterのサイズを動的に変更する

環境

  • Swift4
  • Xcode9

概要

Storyboard上でTableViewにHeaderViewを追加し実行するとUILabel等の高さが変わる時にHeaderViewの高さが変わらずにSubViewが途切れてしまった.
UITableViewController().viewWillLayoutSubviews()をオーバーライドしてコードを追加し,これを解決する.

Example

MyTableViewController.swift

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    
    if let headerView = tableView.tableHeaderView {
        let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
        
        if height != headerView.frame.size.height {
            tableView.tableHeaderView?.frame.size.height = height
        }
    }
}

ZipCode4sをSwift4に対応&BugFix

今までのZipCode4s

インターネットを介して郵便番号のデータを取って来ていた
これからはローカルに置いてあるので遅延が最小になる

Swiftに強い人がプルリクを送ってくれた

.podspecの

s.source_files      = 'ZipCode4s/*.{h,m,swift,csv}'

s.source_files      = 'ZipCode4s/*.{h,m,swift}'
s.resource          = 'ZipCode4s/*.csv'

にすると動いた
.source_filesにファイルを全て書くものだと思っていた...

github.com

ほしい機能等あればissue投げてください
(スターもほしい)

Swift4のsubstringが非推奨になった話 - 'substring(to:)' is deprecated

Swift4からのコード

"abcdefg".substring(to:"abcdefg".index("abcdefg".endIndex, offsetBy: -5))

こういうコードがSwift4からは

"abcdefg"[..<"abcdefg".index("abcdefg".endIndex, offsetBy: -5)]

になります.

ZipCode4sをSwift4に対応させました

github.com

polSearch アップデート情報 2017/09/16

アップデート内容

  • ブックマーク機能追加
  • 広告もちょっぴし追加(バイトしてなくて貯金もほぼないので助けて…
  • スペシャルサンクスページ追加

スクリーンショット

  • インフォボタンの追加(ここからスペシャルサンクスページへ)
  • タブバーを追加(ブックマーク画面との切り替え)

f:id:taillook:20170916232925p:plain

ブックマークのやりかた

  • +ボタンを押すとブックマークに追加出来ます
  • 削除は+ボタンの位置にゴミ箱ボタンが出るのでそれを押すとブックマークから削除できます

f:id:taillook:20170916233304p:plain

ハードタブとソフトタブについて

ハードタブ・ソフトタブ

インデントの種類としてハードタブとソフトタブがある.

ハードタブ

ハードタブはタブ文字 \tを用いてインデントを表現する.

ハードタブのメリット

エディタの設定で幅を変えられる

ソフトタブ

ソフトタブはスペースを用いてインデントを表現する.
(スペースなのにタブって言ってるの面白い)

ソフトタブのメリット

どの環境で見ても同じ幅になる.

おすすめ

www.taillook.tech

私はハードタブが好き

Swift3でシングルトンを試す

シングルトンとは

インスタンスが必ず一つであることを保証したいクラスがあったときにそれを保証してくれるものがシングルトンである.

コード例

class Common: NSObject {
    static let sharedInstance = Common()
    var sharedString = ""

    private init() {

    }
}

利用側コード

class ViewController: UIViewController {
    var test = Common.sharedInstance.sharedString
}

pythonでOpen JTalkを使うサンプル

Open JTalkとは

”Open JTalk”は名古屋工業大学の研究チームが作ったフリーのLinux日本語音声合成エンジンのこと

Open JTalk - HMM-based Text-to-Speech System

インストール方法

環境

  • debian系Linux
  • python 2.7.x

インストール

sudo apt-get install open-jtalk
sudo apt-get install open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001

コード

#-*- coding:utf-8 -*-
import subprocess
from datetime import datetime

def jtalk(t):
    open_jtalk=['open_jtalk']
    mech=['-x','/var/lib/mecab/dic/open-jtalk/naist-jdic']
    htsvoice=['-m','/usr/share/hts-voice/mei/mei_normal.htsvoice']
    speed=['-r','1.0']
    outwav=['-ow','open_jtalk.wav']
    cmd=open_jtalk+mech+htsvoice+speed+outwav
    c = subprocess.Popen(cmd,stdin=subprocess.PIPE)
    c.stdin.write(t)
    c.stdin.close()
    c.wait()
    aplay = ['aplay','-q','open_jtalk.wav']
    wr = subprocess.Popen(aplay)

def say_datetime():
    d = datetime.now()
    text = '%s月%s日、%s時%s分%s秒' % (d.month, d.day, d.hour, d.minute, d.second)
    jtalk(text)

if __name__ == '__main__':
    say_datetime()

3 ハードタブ インデント をはじめよう

3ハードタブインデントとは?

3文字分のtab文字でインデントを表現すること

例(例外的に3スペース)

#include <stdio.h>

int main(void) {
   printf("Hello World!\n");
   return 0;
}

NEWGAMEのねねっちも採用

このサイトのキャプチャからねねっちのコードを見ると3つスペースが空いてることがわかる

anihatsu.com

ハードタブとソフトタブ

  • ハードタブは\tとして表現される
  • ソフトタブは自動でスペースとして表現される

それだけ

なぜハードタブか

エディタの設定は人それぞれ.
2スペースインデントのコードを普段4スペースの人が読んだとき,「は?」となるはず
ハードタブなら\tなのでその人の環境によって幅が自動で調節される

.vimrcでの設定

set tabstop=3 " 画面上でタブ文字が占める幅
set softtabstop=3 " 連続した空白に対してタブキーやバックスペースキーでカーソルが動く幅
set autoindent " 改行時に前の行のインデントを継続する
set smartindent " 改行時に前の行の構文をチェックし次の行のインデントを増減する
set shiftwidth=3 " smartindentで増減する幅

bash上でC言語のプログラムを即時実行

やり方

.bash_profileに以下を記入

function shellc () {
  gcc $1 -o ~/.out && ~/.out
}

試す

test.cを作成

#include <stdio.h>

int main(void) {
    printf("Hello World!\n");
    return 0;
}

bash上で実行

USER$ shellc test.c 
Hello World!