非常に大きなデータセット(数百万のアイテム)を扱う場合、MacOSアプリケーションではアクションを完了するのにかなりの時間がかかることがあります。ユーザーにアプリが動作していることを知らせるために、温度計のような進捗状況をツールバーの特別なビューに表示します。これはもともと、ヨセミテで2,3年前に開発されたもので、10.9と10.10で動作してもうまく動作します。しかし、Sierraでは動作しません(10.11については不明ですが、テストするシステムはありません)。NSViewの表示コードがYosemiteで動作していましたが、MacOSで動作しませんSierra
これは動作しているときの様子で、30%の進捗状況を示しています。この効果は、Xcodeのツールバーに表示されるビルドの進行状況とよく似ています(Xcodeと同様に、他の情報もバナーに表示されるため、NSProgressIndicatorを使用していません)。
プログレスバーはNSButtonのサブクラスであるInfoBannerViewというクラスを使用して、表示されています。このクラスのdrawRect:メソッドを示します(明快にするために、背景とテキストを描画する非進行コードは省略されています)。 progressValueは0と1の間の値をとるプロパティです。このメソッドはサーモメーターのようにビューの幅のパーセンテージを塗りつぶす丸い四角形を描きます。
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
NSRect bannerRectangle = [self bounds];
{
NSColor* progressColor = [NSColor colorFromHexRGBString:@"85ade1"];
... draw outline and background of banner
if (progressValue > 0.0f && progressValue < 1.0f) {
[progressColor setFill];
NSRect progressRect = NSInsetRect(bannerRectangle, 1.0, 1.0);
CGFloat progressWidth = progressRect.size.width * progressValue;
progressRect.size.width = progressWidth;
NSBezierPath* roundedProgressPath = [NSBezierPath bezierPathWithRoundedRect:progressRect xRadius:4 yRadius:4];
[roundedProgressPath fill];
}
... draw text on banner
}
}
このようなルックスを実行するのに長い時間がかかるコード:
for {
... do stuff that takes a long time
InfoBannerView * ibv = [windowController recordCountView];
[ibv setProgress:value];
[ibv display];
}
ライン[ibv display]
はすぐに実行ループを待たずに、進捗バナー表示を更新することになっています。 (注:パフォーマンス上の理由から、私は実際にはループを介して表示しませんが、わかりやすくするためにコードを削除しました)。
このコードをMac OS X 10.10で実行すると、完全に動作します。作業が実行されると、進行状況バーが徐々にバナー表示を満たします。
ただし、このコードをmacOS 10.12 Sierraで実行すると、何も表示されません。私は、drawRect:code はが繰り返し呼び出されていると判断しました。正しいオブジェクトが呼び出されています。すべての寸法と値が正しい。唯一の問題は何も描かれていないことです。 (drawRect:が正常なビューの更新中に呼び出されたときに描画が適切に行われます)progressValueを0.3に強制すると、ビューの更新時にコードが適切に描画されることが判明しました。 )
10.10 SDKにリンクされていた古いバージョンのアプリケーションを実行しようとしました。 via -displayで呼び出されたときの描画はまだありません。 10.10以前のバージョンでのみ動作します。
私はこれを書いて、雲が上がり、答えが明白になることを望んでいたが、そのような運はなかった。 10.11リリースノートまたは10.12リリースノートに関連するものはありません。たぶん私は間違っていた何かばかなことをやっているし、私はそれが今まで働いて幸運だと思う?この時点で、私はアイデアがありません。
コントロールはクリック可能なボタンですか? – Willeke
@Willekeこの投稿が書かれた時点で、InfoBannerViewはNSButtonのサブクラスでした。しかし、NSButtonの機能を実際に使用していなかったので、昨夜私はそれをNSButtonのサブクラスに変更して、NSButtonが問題かどうかを確認しました。そうではありませんでした。 (バナーはクリック可能で、クリックはmouseDown:メソッドで処理されます)。 –