2019年2月22日金曜日

StackViewの優先度 Content Hugging PriorityとContent Compression Resistance Priority


こんにちは、オフィス狛 モバイル開発担当 Aika-yuy です。
今回の投稿は、 StackViewにつけるAutoLayoutの優先度について書いてみたいと思います。


サイズが曖昧だと怒られる

動的なサイズ変更や、デバイスサイズにも柔軟に対応してくれるStackViewですが、サイズが曖昧だと怒られることがあります。固定サイズを指定するという方法もありますが、iPad対応で文字のサイズを動的に変更したい場合は、あらかじめ優先度を設定しましょう。

まず、StackViewに2つのLabelを配置し、StackViewのサイド20、Y軸の中心になるように制約をつけます。











そうすると、こんなエラーが出ます。







『どっちをLabelサイズを優先すればいいかわからないよーー 』ということです。
こまちゃんのLabelの優先度を低くするようにアドバイスしてくれています。

優先度を指定する

優先度を変更するときはAutoLayoutで設定できます。
優先度は、高くしたい方のpriorityを高くするのではなく、低くしたい方のpriorityを低くするようです。

いろんな解釈の仕方があると思いますが、私が覚えやすい方法使い分けをで書いてみました。

・Content Hugging Priority・・・・・・・・・・  子Viewが親Viewより小さい時 

・Content Compression Resistance Priority・・・  子Viewが親Viewより大きい時 


子Viewが小さい時

2つのLabelどちらともの文章が短い時、どちらのサイズを大きくしてViewいっぱいに表示するかを指定しなければいけません。
その場合は、優先順位が低い方の(固有のサイズを保持しなくてもいい方、大きくなってもいい方)
Content Hugging Priorityを1小さく設定します。

下の画像では、nameは動的にサイズが変更する予定がないので元々のサイズを維持。こまちゃん部分は動的にサイズ変更したいというような場合です。
こまちゃんのLabelのContent Hugging Priorityを下げることにより、長くなってしまった場合省略表示され、nameのラベルを親Viewから押し出すこともなくなります。











子Viewのどちらかが大きい時

2つのLabel合わせたサイズが親Viewよりも大きくなってしまう場合、どちらを優先して表示するか指定します。
省略して表示してもいい方の優先度を1小さくします。










子Viewどちらとも親Viewより大きい時(どちらかを優先すると、どちらかが消えてしまう場合)

この場合は、設定次第ですがどちらも表示したい場合は親のStackViewの比率から固定サイズで指定した方がいいかもしれません。

AutoLayoutマスターになるべく、少しづつブログも更新していけるよう頑張ります。



,

2019年1月31日木曜日

gitマージツールにWinmergeを使う方法。

オフィス狛 技術部のHammarです。

開発するとき、特に複数人で開発をされる場合は、gitを使われている方が多いと思います。その際に皆さんはマージツールやdiffツールに何を使っていますでしょうか?
私は開発はwindowsを使うことがほとんどなので、WinMergeというマージツールをよく使っています。なので、これをgitのマージツールとして設定していますが、今回はこのgitのマージツールの設定方法について書いてみたいと思います。

ちなみに自分のgitクライアントツールですが、自分はGitExtensionsを使っています。GitExtensionsはデフォルトでkdiffというマージツールが使えるようになっていますが、個人的には使いづらくて、マージツールの設定方法を変えられてうれしかった記憶があります。

設定はプロジェクトにある「.git」というディレクトリ内の「config」ファイルに下記の記述をそのまま追加して保存するだけでOKです。※.gitは隠しファイルとなっています

■config

[diff]
    tool = WinMerge
[difftool "WinMerge"]
    path = C:/Program Files/WinMerge/WinMergeU.exe
    cmd = \"C:/Program Files/WinMerge/WinMergeU.exe\" -f \"*.*\" -e -u -r \"$LOCAL\" \"$REMOTE\"
[merge]
    tool = WinMerge
[mergetool "WinMerge"]
    path = C:/Program Files/WinMerge/WinMergeU.exe
    cmd = \"C:/Program Files/WinMerge/WinMergeU.exe\" \"$MERGED\"

ひとまず上記で最低限の設定となりますが、この記述はいろいろとカスタマイズ可能なので、自分用に見やすくしたり、3画面構成にしたりとかcmdの記述部分でいろいろとオプション設定も可能なので、もっと細かく設定してとことん使いやすくするのもありだと思います。

もちろんクライアントツールで設定を変えることも可能ですが、ツール毎に設定画面も違いますし、この方法はconfigファイルに記述するだけなのでGitExtensions以外のツールでも同じやり方で使えるようになります。

とりあえず細かな設定は置いといてサクッとgitでWinMergeを使いたいときにはぜひご活用ください。


Angular Templateでリストのフィルタを行う。


オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。

今年最初のブログ、何とか1月中に出来ました。(ギリギリ)
今年最初はAngularネタで行きたいと思います。

AngularのTemplate(html)でリストのデータを表示する際、
<ng-container *ngFor="let item of testList>
  <div class="test_class">{{ item.name }}</div>
</ng-container>
こんな感じの書き方をすると思います。
この時、「リスト内のデータをフィルタしてから表示したいんだよなー」と思う時がありませんか?
ありません?ないかな・・・・まあ、私はあります。

というわけで、こんな時は「Pipe」を使います。
以前、『AngularのPipeを使ってhtml(View)の表示を共通化する。』をブログに書きましたが、あの「Pipe」です。

では、いつものようにAngular CLIで作成します。コマンドは、
ng g pipe [path/name]
です。今回は、「list-filter」という名前で作ります。
$ng g pipe shared/list-filter
CREATE src/app/shared/list-filter.pipe.spec.ts (204 bytes)
CREATE src/app/shared/list-filter.pipe.ts (209 bytes)
UPDATE src/app/shared/shared.module.ts (711 bytes)

すると、以下のようなファイルが生成されます。
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'listFilter'
})
export class ListFilterPipe implements PipeTransform {
  transform(value: string, args?: any): any {
    return null;
  }
}

これを以下のように変更します。
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filter'
})
export class ListFilterPipe implements PipeTransform {
  transform(items: any[], col: string, value: string): any {
    if (col.length === 0 || value.length === 0) {
      return items;
    }
    return items.filter(x => x[col] === value);
  }
}
Pipeの名前は分かりやすく「filter」にしています。

そして、transformの引数を以下のように変更しました。
第1引数:items: any[] → 対象のリスト
第2引数:col: string → フィルタを行う対象の項目名
第3引数:value: string → フィルタする値

実際は色々作り込むのですが、とりあえず、今回は、
フィルタする項目・値が無かったら、リストをそのまま返すようにして、
if (col.length === 0 || value.length === 0) {
  return items;
}
最後にリストのフィルタした結果を返しています。
return items.filter(x => x[col] === value);
では、実際にこのPipeを使ってみましょう。

リストの中身はこんな感じだとします。(分かりやすくする為に、json形式で書いています。)
{"hoge_list":[
  {"id":"1","name":"テスト1"},
  {"id":"2","name":"テスト2"},
  {"id":"3","name":"テスト3"},
  {"id":"4","name":"テスト4"},
  {"id":"7","name":"テスト7"}
]}

実際にTemplateで使用する場合は以下のように記載します。
<ng-container *ngFor="let item of testList | filter:'id':'7">
  <div class="test_class">{{ item.name }}</div>
</ng-container>
@Pipe の name をvertical lineでリストの後ろにつけて、Pipeの後ろは、「:(colon)」を繋げてPipeへの引数を記載します。
つまり、「testList | filter:'id':'7'」の部分で、リスト内の「id」という項目が「7」になっている値を絞り込んでいます。

出力結果は、
 テスト7
となります。

如何でしょうか。Pipe、色々な使い方がありますね。

それでは、良いAngularライフを!