iOSDCに参加した #iosdc
会場が練馬って朝知ったので遅刻した。
到着即ランチセッション #iosdc
— ひらり (@hiragram) 2016年8月20日
ランチセッションの弁当がうまそう pic.twitter.com/UhgOb9hRRp
— ひらり (@hiragram) 2016年8月20日
ベストトーク賞とられたReactive Programmingの話。
FRP、もうちょっとソルジャーの人たちが頑張って世界を平和にしてから自分がやり始めるでもいいかなあと思ってるんだけどだめかな #iosdc
— ひらり (@hiragram) 2016年8月20日
メモリ管理の話。
weak referenceだけの状態になってもまだメモリは解放されていなくて、次に参照された時にnilを返して実際に解放される?ってこと? #iosdc
— ひらり (@hiragram) 2016年8月20日
デザイナーにStoryboard使ってもらう話。
Borderのビューは毎プロジェクト作るけどIBDesignableにしたことなかったな #iosdc
— ひらり (@hiragram) 2016年8月20日
デバッグの話。
DiagnosticsとSymbolic Breakpointはあんま使ったこと無いので勉強しよ #iosdc
— ひらり (@hiragram) 2016年8月20日
余談
個人スポンサーTシャツ、Lサイズで申し込みしてて受付でもLですね〜って言われたんだけど今朝着ようと思って見たらSだった どうにかならんかな #iosdc
— ひらり (@hiragram) 2016年8月22日
追記
@hiragram ごめんなさい!予備がありますので、DMで住所とお名前を頂けますか。Lサイズをお送りします。
— iOSDC (@iosdcjp) 2016年8月22日
対応ありがとうございます。
さらに追記
@hiragram やせろ
— いかもん (@ikamooon) 2016年8月22日
うるせえ!!!!!!!!!!!!!!!!!!!!!!!
NSTextFieldをAutoLayoutで配置すると幅が0になっちゃう
最近趣味プログラミングでAppKitを触っている。
AppKitについて言いたいことはいろいろあるがUILabel代わりに使ったNSTextFieldについてハマったので書いておく。
Slackのメッセージみたいな見た目のビューを作りたくてAutoLayoutでごちゃごちゃ配置してたらNSTextFieldの幅がゼロになってしまって困った。
目指していた形はこんなの。
で、当初ふつうに配置して制約かけたら
こんなんなった。Xcodeのビューの階層見れるアレ(名前知らん)で見たらこんなん。
いる。
幅0のNSTextField2つと、なんか中途半端に生き残ったNSTextFieldがいる。
最初に疑ったのはAutoLayoutで、自分で書けた制約のプライオリティとか、Content Compression Resistance Priorityなんかを気にしていろいろいじってみたが全然改善されず、1時間くらい浪費した。
Content Compression Resistance Priorityについて調べなおしていたら、intrinsicContentSize
にたどり着いた。
Custom views typically have content that they display of which the layout system is unaware. Setting this property allows a custom view to communicate to the layout system what size it would like to be based on its content. This intrinsic size must be independent of the content frame, because there’s no way to dynamically communicate a changed width to the layout system based on a changed height, for example.
つまりContent Compression Resistance Priorityで登場するビューの固有サイズというのはこいつのことらしい。かけられた制約が固有サイズより大きかった時の固有サイズの優先度がContents Hugging Priority、逆に制約が固有サイズより小さかった時の固有サイズの優先度がContents Compression Resistance Priorityということだ。
で、stringValue
をセットしたあとのNSTextFieldのintrinsicContentSize
を見ると
AppKitの一番気に入らない部分の真似します
— ひらり (@hiragram) 2016年8月18日
(lldb) po nameLabel.intrinsicContentSize
— ひらり (@hiragram) 2016年8月18日
▿ CGSize
- width : -1.0
- height : 21.0
width: -1.0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
— ひらり (@hiragram) 2016年8月18日
自分でかけた制約に問題はなく、Content Compression Resistance Priorityにも問題はなく(そもそも触ってない)、AutoLayoutやめてsizeToFit()
でサイズ決めて配置したとしてもintrinsicContentSize
のwidthは-1.0なので見えないままでしたよ、という結構きついハマりだった。
対応めんどくさかったら投げ出して帰るつもりだったが、StackOverflowにまさにその回答があった。
-[NSTextField intrinsicContentSize] always has undefined width - StackOverflow
この一番voteを稼いでる回答(というか質問者が自己解決したっぽい)によると、
OK, finally figured it out…
[_textfield setEditable:NO]
That's it. I guess that with an editable textfield one must have an explicit constraint for the textfield width. Which kind of makes sense, imagine editing a textfield and it would constantly grow horizontally with every keystroke... not an ideal UI.
僕はSwiftなので
nameLabel.editable = false
これでいけた。他のNSTextFieldも同じ。
Content Compression Resistance Priorityが具体的にどう動くのかを把握してなかったので時間くってしまった。
AutoLayoutに関して僕が良いなと思ったおすすめの本はこちら。
よくわかるAuto Layout iOSレスポンシブデザインをマスター
- 作者: 川邉雄介,所友太
- 出版社/メーカー: リックテレコム
- 発売日: 2016/06/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
いやーはまったはまった。
awakeFromNibのドキュメント読んだ
awakeFromNib
ちゃんと理解してる自信がなかったので読んでみた。
Prepares the receiver for service after it has been loaded from an Interface Builder archive, or nib file.
Interface Builder archiveもしくはnibファイルから読み込まれたあとに、サービスに必要なレシーバを用意します
The nib-loading infrastructure sends an
awakeFromNib
message to each object recreated from a nib archive, but only after all the object in the archive have been loaded and initialized.
nib読み込み基盤はnib archiveから再生成されるオブジェクトが読み込まれ、初期化されたあとにawakeFromNib
メッセージを送ります。
When an object receives an
awakeFromNib
message, it is guaranteed to have all its outlet and action connections already established.
オブジェクトがawakeFromNib
メッセージを受け取った時、そのオブジェクトのoutletとactionはすでに初期化されていることが保証されます。
You must call the
super
implementation ofawakeFromNib
to give parent classes the opportunity to perform any additiional initialization they require.
親クラスが必要とする初期化を実行するために、super classのawakeFromNib
を呼びださなければいけません。
Although the default implementation of this method does nothing, many UIKit classes provide non-empty implementations.
このメソッドのデフォルト実装では何も処理されないが、多くのUIKitのクラスはこのメソッドで何らかの処理が行われている。
You may call the
super
implementation at any point during your ownawakeFromNib
method.
super classのawakeFromNib
を呼び出すのは、自分のawakeFromNib
メソッド内のどこでも良いです。
NOTE During Interface Builder's test mode, this message is also sent to objects instantiated from loaded Interface Builder plug-ins.
Because plug-ins link against the framework containing the object definition code, Interface Builder is able to call their
awakeFromNib
method when present.The same is not true for custom objects that you create for your Xcode projects.
Interface Builder knows only about the defined outlets and actions of those objectsl it does not have access to the actual code for them.
このNOTEはまだ理解が追いついてないので省略
During the instantiation process, each object in the archive is unarchived and then initialized with the method befitting its type.
生成プロセスの間、archive内のそれぞれのオブジェクトはunarchiveされそれぞれの型にしたがって初期化されます。
Objects that conform to the
NSCoding
protocol (including all subclasses ofUIView
andUIViewController
) are initialized using theirinitWithCoder:
method.
NSCoding
プロトコルに適合するオブジェクト(UIView
およびUIViewController
のすべてのサブクラスを含む)はinitWithCoder:
メソッドによって初期化されます。
All objects that do not conform to the
NSCoding
protocol are initialized using theirinit
method.
NSCoding
プロトコルに適合しないオブジェクトはinit
メソッドによって初期化されます。
After all objects have been instantiated and initialized, the nib-loading code reestablishes the outlet and action connections for all of those objects.
すべてのオブジェクトが生成され初期化されたあと、nib読み込みコードは再びそれらのオブジェクトのoutletとactionを有効にします。
It then calls the
awakeFromNib
method of the objects.
そしてそのオブジェクトのawakeFromNib
をコールするのです。
For more detailed information about the steps followed during the nib-loading process, see
Nib Files
in Resource Programming Guide.
もっとnib読み込み処理の続きを知りたかったらResource Programming GuideのNib Files
の項を見てな。
IMPORTANT Because the order in which objects are instantiated from an archive is not guaranteed, your initialization methods should not send messages to other objects in the hierarchy.
オブジェクトがarchiveから生成される順番は保証されていないので、初期化メソッド(=イニシャライザ?)内で他のオブジェクトにメッセージを送るべきではありません。
Messages to other objects can be sent safely from within an
awakeFromNib
method.
awakeFromNib
メソッド内では他のオブジェクトに安全にメッセージを送ることが出来ます。 (= 既に初期化が済んでることが保証されているから、かな)
Typically, you implement
awakeFromNib
for objects that require additional set up that cannot be done at design time.
一般に、デザイン時に出来ない (= xib上で出来ない?) セットアップをする処理をawakeFromNib
に実装します。
For example, you might use this method to customize the default configuration of any controls to match user preferences or the values in other controls.
例えばこのメソッドを、あるコントロールのconfigurationをユーザー設定や他のコントロールの値によって決めたい時などに利用できます。
You might also use it to restore individual controls to some previous state of your application.
また、アプリケーションの過去の状態に応じてそれぞれのコントロールをリストアしたいときにも使うことが出来ます。
英語学習を初めて2ヶ月経ったのでやってることとやめたことを書く
私は英語チョットデキルになりたいので、そのためにチョットがんばることにしました。 去年の12月らへんからいろいろ始めて、だいたい2ヶ月くらい経ったので、やってることとかやったけどやめたこととか書く。
「ワタシハ リナックス チョットデキル」Tシャツを着るリーナス・トーバルズ(Linus Torvalds)の勇姿その2。 #Linuxcon pic.twitter.com/46eMSkUX4U
— shigetaka@256将軍_発売中 (@shigetaka256) 2014, 5月 21
やってること
エンジニアが0から英語を勉強する為にした事 に多大な影響をうけた。
DMM英会話
DMM英会話以外のオンライン英会話は試してないので、的外れだったらごめんなさい。
やってる中で一番英語っぽい活動はこれ。まだ始めて2週間くらいだけど、めっちゃ楽しい。 月5000円で1回25分のレッスンを1日1回受けられる。無料体験が2回分ついてるのでとりあえずやればいいっす。
これは主観ですが、ITのエンジニアみたいな仕事してる人は多分日本人の一番英語できない層よりは100倍くらい英語できると思います。 DMM英会話の講師の方々は、我々よりも100倍英語できない人たちに教えるの慣れてる(と信じてる)ので、臆すること無く突っ込んでいって、そして大爆死しましょう。僕はしました。
弊社技術顧問のまつもとゆきひろさんも、DMM英会話を体験しています。
まつもとゆきひろ、初めてのオンライン英会話を体験【DMM英会話】
僕は勝手に社内でDMM英会話エバンジェリストを自称して騒いでるんですが、うまく乗せて始めさせた2人のエンジニアは既に無料枠を使い切り月5000円払ってレッスンを受けています。
DMM英会話はかなり自由度が高い印象で、テーマを指定しないフリートークだったり提供される教材を使ったレッスンだったり選択肢が広いです。
今までに僕がやったレッスンの内容は
- フリートーク
- こちらからガンガン話せないうちはあんまりおすすめしない。初回にこれやって普通につらかった。
- 自己紹介の練習
- 自身のこと、仕事のこと、住んでる場所のことなど。
- 瞬間英作文
- http://eikaiwa.dmm.com/material/shunkan_eisakubun/
- 日本語の短い文章を、英文に翻訳して喋る練習。
- 1セクションだいたい10分くらいで終わる。
- Dainy news / Daily news for beginners
- http://eikaiwa.dmm.com/beginnerdailynews/
- DMMが毎日更新するニュース記事を朗読したり、質問に答えたりする。
- for beginnersがあるのを知らないで難しい方やっててつらい思いをした。それ以来簡単な方やってる。
こんな感じ。他にも教材めちゃめちゃあるので、自分に合ったのを探せばいいと思います。 http://eikaiwa.dmm.com/material/
個人的には、英会話初めての人には瞬間英作文の一番最初からやるのおすすめ。This is a penレベルからできるので、「とりあえず音を出す」ことに慣れるのにちょうどいい。
同じ音声を何度も聞く
いろんなのをめちゃめちゃ聞くって言うよりは、おんなじのを何度も何度も聞くのがいいと思う。 よく聞いているのは、
- Rebuild.fm 122: The Metal Is Dead(tenderlove)
- Steve Jobs' 2005 Stanford Commencement Address
- 故Steve Jobs氏がスタンフォード大学の卒業式で講演したときの動画。
- ジョブズの英語も個人的には聞き取りやすいと感じます。
- 講演なのでしゃべりも丁寧だし、耳を慣らすにはちょうどいい。
- 文字起こしはこちら。 http://news.stanford.edu/news/2005/june15/jobs-061505.html
特にRebuildの方は、二人が対談している音声なので、生の会話という感じがしてよい。 あと文字起こしが非常に秀逸。"You know,"とか"I mean,"みたいな「いや、」「えっと、」みたいなキャッチしなくていい単語は文字起こしに無いので、「無視していい部分」がわかるようになりました。会話の端々に"you know"って言われて「俺いまなんか聞かれた?」と混乱しなくて良くなります。 文字起こしに出てきた知らない単語はそのままiPhoneの辞書でしらべてQuizletに登録。
書く
流石にコード書くだけで英語書けるようにはならないので、英文を生み出す作業も意識してやっています。 例えばライブラリの挙動がようわからんときにIssueを立ててみたり、サービスの使い方がわからんときにサポートにチャットを投げてみたり。 直近ではAppseeのサポートの人とかなり長くやりとりをしました。どういうふうにインストールしたか、どういう実装か、他にどんなライブラリが入ってるか、みたいなのをうまく説明する英文を書くのはとても勉強になります。 テクニカルな文脈だと普段の英語学習で触れないような長い単語とかに触れるので、エンジニアとしてはここのスキルも伸ばしておきたい。
Siriを英語にする
Siriで発音チェックできる。 発音記号どおりの綺麗な発音じゃなくても結構聞き取ってくれるので、「これくらい雑でも通じるもんだな」という感覚を得られる。 逆に、Siriでも拾えないとなるとやべえぞという感じ。 1単語だけだといけるけど、文章になるととたんに認識しなくなる、みたいなのはよくあると思う。 僕はもともとSiriをよく使う習慣があったので、いい発音練習の機会になってる。
- Turn on all alerms(めざまし全部オンにして)
- Wake me up at 8 tomorrow(明日8時に起こして)
- How is the weather today(今日の天気は)
みたいなかんじ。
やったけど今はやってないこと
海外のペンパルを作る
冒頭で紹介したブログにもあった、「海外の友達とチャット」みたいなのはちょろっとやってみたんだけどあんまり続かなかった。 確かに日本人とやりとりしたがる外国人すごいたくさんいるんだけど、時差あるから全然レス返ってこないとか、iPhoneで英文打つのつらすぎるとか、向こうは日本語教わるつもりでくるからやりづらいとか、いろいろ要因があってやらなくなってしまった。
英語でメモを取る
コードを書きながらちょっとした設計を整理しておきたいときとか、走り書きでメモを残すようなときに英語で書くようにしてみた。 中学の時にかっこつけて筆記体の練習しまくってたおかげで、メモを取ること自体そんなに難しくなかった。 狙いとしては、脳内で考えたことを素早く英文で表現することで、結構頭も使うしよい取り組みだったと思う。 正しい英語っていうよりは、より早く言いたいことを表現することを目指してたので、今読み返すと文法が崩壊しすぎている。 頭を使うのであんまり続かなかった。
Macの言語設定を英語にする
これも普段から英語に触れることを目的にやった。 ほぼ困ることは無いんだけど、メニューの項目とかたまに難しいのがいっぱい並んでる時があって、そのたびに単語調べて〜とかやってたのが時間の無駄だった。 頭も仕事をするつもりでいるので、英語学習モードになってない感じがして全然身にならないなと思って半日でやめた。
所感
中学の頃から英語の成績はよかったけど、こと英会話に関してはまったく練習したことが無かったので、最初は脳の負荷が異常に高い感じがしたけど、2週間くらい無理してやってみると意外となんとかなる気がしてくる。
「英語やんなきゃなー」みたいなのはずっと前から漠然と思っていたけど、実際に始めてみると過去の自分はやんなきゃなーとか危機感抱いてるつもりみたいな状態で満足してたんだなあと感じる。明確にやりたいと思ってるならやるだろうと。
とりあえず、
- DMM英会話無料体験枠をさっさとやる
- 聞く
- 書く
やればいいと思います。
Apple Watchにはカバーつけたほうがいい
## Apple Watchめっちゃぶつける
Apple Watch ケース, Spigen? アップル ウォッチ (42mm) ラギッド・アーマー 液晶保護フィルム 2枚入 【国内正規品】 (2015) (ホワイト【SGP11497】)
- 出版社/メーカー: Spigen
- メディア: エレクトロニクス
- この商品を含むブログを見る
Apple Watch ケース, Spigen? アップル ウォッチ (42mm) ラギッド・アーマー 液晶保護フィルム 2枚入 【国内正規品】 (2015) (ブラック【SGP11496】)
- 出版社/メーカー: Spigen
- メディア: エレクトロニクス
- この商品を含むブログを見る
Apple Watch ケース, Spigen? アップル ウォッチ (38mm) ラギッド・アーマー 液晶保護フィルム 2枚入 【国内正規品】 (2015) (ブラック【SGP11485】)
- 出版社/メーカー: Spigen
- メディア: エレクトロニクス
- この商品を含むブログを見る
Apple Watch ケース, Spigen? アップル ウォッチ (38mm) ラギッド・アーマー 液晶保護フィルム 2枚入 【国内正規品】 (2015) (ホワイト【SGP11486】)
- 出版社/メーカー: Spigen
- メディア: エレクトロニクス
- この商品を含むブログを見る
Swiftのイニシャライザややこしかったのでまとめた
- 既定イニシャライザ(default initializer)
- 引数なし。
- イニシャライザが1つも定義されておらず、すべてのプロパティの初期値が設定されている時に利用可能になる。
- ベースクラスの既定イニシャライザは指定イニシャライザとして機能する。
- 指定イニシャライザ(designated initializer)
- 簡易イニシャライザ(convenience initializer)
- 他のイニシャライザを呼び出して初期化を行うイニシャライザ。
- 同じクラスの他のイニシャライザを呼び出して利用するが、直接あるいは間接的に指定イニシャライザを呼び出していなければならない。
convenience
キーワードがつく
あるクラスの簡易イニシャライザを呼ぶと、スーパークラスのイニシャライザを順番に呼んでいき、ベースクラスの指定イニシャライザが実行された後に自分のクラスのプロパティに値を入れられるようになる。
指定イニシャライザは、スーパークラスのイニシャライザを叩く前に、そのクラスで追加された変数、定数の初期化を済ませていなければならない。
サブクラスのイニシャライザは、スーパークラスのイニシャライザを呼ぶ前に、スーパークラスのプロパティにアクセス出来ない。
イニシャライザは、ベースクラスの変数、定数の初期化が終わるまでインスタンスメソッドやプロパティにアクセスしたり、selfを値として扱ってはいけない。そういう時はタイプメソッドにしましょう。
iOSのバージョンによってはUIAlertControllerのボタンの並びが変になるかもしれない
古いiOSだとUIAlertControllerにaddActionした順に左から表示されるっぽい。 たまたま古いテスト機で触ってて違和感があって発見。
こんなコードが
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) showDialog() } func showDialog() { let message = "OK,キャンセルの順" // ↓ここのaddActionする順番を逆にしたりすると let alert = UIAlertController(title: "title", message: message, preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil)) alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil)) presentViewController(alert, animated: true, completion: nil) } }
iOS8.4
iOS8.1
iOS8.1だと足した順に左からになってて、8.4だと常にOKが右に来てる。
シミュレータではiOS9.0を動かしてたので、たまたま古いiPhone5でテストしなかったら気づかなかった。
こういうの他にもありそうで怖い。