UILabel に背景色をつけたら上と右に影ができることがある

UILabel に背景色をつけた状態で、表示サイズを計算して幅と高さを指定すると、Label 上側と右側に影のような線が出る場合があることを発見しました。

設定する文字列によっては影のような線は出ないこともあります。

デザイン的には良くなく、この影(線)を出さないようにしたいので、原因を探っていたところ、どうやら幅と高さの数値に問題があるようでした。

幅や高さの数値が整数でない場合(小数点以下がある場合)に発生してしまうようでした。

おそらく、内部の処理で小数点以下がある場合はアンチエリアスみたいな形で処理をしてしまっているのではないかと思います。

Width と Height の数値を ceil 関数で 小数点以下をなくしたら消えてくれました。

ビルドをアップロードしようとしたらエラー

アプリのアップデートをAppStoreに申請しようと思い、XCode からビルドをアップロードしてみたら、以下のエラーが発生しました。

Unable to process lookupPurpleSoftwareVersions request at this time due to a general error.

 

2,3日前まではできていたので、Apple のサーバ側で何かトラブルかなと思い、数時間たってから再度挑戦してみたのですが、エラーが継続したままでアップロードできません。

それなら Application Loader を使ってやってみようと思い、試してみたのですが、ApplicationLoaderでも同じエラーでアップロードできません。

もしや、ツールのバージョン?

と思いバージョンを調べてみると、XCode は 5.1.1 ApplicationLoader は 2.7 でちょっと古いものでした。

XCode のバージョンを上げるといろいろとめんどくさそうなので、それは後にして、ApplicationLoaderを3.0に更新してみました。

アップロード完了!

できました。

バージョンが古かったのが原因でしょうか。

iTunes Connectの画面には XCode 5.1.1 以降でって書いてあるので5.1.1でも大丈夫だと思っていたのですが、、、

iTunes Conenct で「App アイコンを作成できませんでした」というエラーになる

iOS アプリのバージョンアップ申請をしようとしたら、iTunes Connect で

アイコン画像をアップしてください

というエラーになった。

前回のバージョンでもアップしているのに引き継がれないのかなと不思議に思いながら画像ファイルをアップロードして保存。

すると

App アイコンを作成できませんでした。

というエラーメッセージが発生。

サイズが大きすぎるのかと思い 512×512 のものを作成してアップしたら

App アイコンのサイズは 1024×1024 にする必要があります。

というエラー。

PNGファイルがいけないのかと思い、jpg ファイルにしてアップ

App アイコンを作成できませんでした。

RGB の設定とか、画像加工ソフトとか、いろいろ変えてみましたがエラーは変わりません。

もう打つ手がありません。。。

これは、時間が経つと直るパターンか、と思い1時間ぐらい何もせずに待ちました。

一時間後に再度同じファイルで挑戦

OK!

できました。

iTunes Connect はたまに原因不明のエラーが出ることがあります。

そして時間がたつと自然に直ることがあります。

わけのわからないエラーが出た場合は、しばらく待ってから試してみましょう。

 

iOS 8 で viewDidAppear が呼ばれなくなった

iOS アプリの開発をしていて、不思議な現象が発生しました。

iOS 7 以前のバージョンでは viewDidAppear が呼ばれるのに、同じコードで iOS 8 だと呼ばれないのです。

かなりハマりましたが、原因はコードの記述ミスでした。

スーパークラスで以下のような記述をしてしまっていました。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewDidAppear:animated] ;
    // :
    // :
    // :
}

そう、viewWillAppear の中で super の viewDidAppear を呼んでしまっていました。

iOS 7 以前ではこんなことをしてもタマタマうまく動いていたと思われます。

iOS 8 になって、内部の処理がすこし変わって顕在化したものと思われます。

こんなミスはレアケースかと思いますが、一応共有ということで記載しました。

 

NSDateFormatter 日付・時刻を文字列にして取得する

現在の日付やデータの更新日時などを文字列にして表示したい場合は NSDateFormatter が利用できます。

NSDateFormatter の setDateFormat でどのような形式の文字列にするのかを指定した後に、日付・時刻を表す NSDate のインスタンスを渡して文字列にします。

サンプルは以下の通りです。

(サンプルでは現在の時刻を取得して文字列に変換しています)

年/月/日 時:分:秒 のサンプル

- (void)sampleNSDateFormatterYYYYMMDDHHMMSS
{
    NSDate *date = [NSDate date] ; // 現在時刻
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init] ;
    [dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"] ;
    NSString *dateString = [dateFormatter stringFromDate:date] ;
    
    [self outputResult:dateString] ; // 結果出力用
}

年/月/日 時:分:秒 の出力結果

出力はこんな感じになります。

NSDateFormatter_1_236

月を Jan Feb などの3文字の英語表記にした文字列を取得するサンプル

月を数字で出すときは MM を指定しましたが、3文字の英語表記の場合は MMM を指定します。

- (void)sampleNSDateFormatter3LettersMonth
{
    NSDate *date = [NSDate date] ; // 現在時刻
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init] ;
    [dateFormatter setDateFormat:@"MMM. dd,yyyy"] ;
    NSString *dateString = [dateFormatter stringFromDate:date] ;
    
    [self outputResult:dateString] ; // 結果出力用
}

月を Jan Feb などの3文字の英語表記にした文字列の出力結果

NSDateFormatter_1_456

月を January February などの英語表記にした文字列を取得するサンプル

月を3文字の英語表記にする場合は MMM を指定しましたが、単語全部を表示する場合は MMMM を指定します。

- (void)sampleNSDateFormatterFullLettersMonth
{
    NSDate *date = [NSDate date] ; // 現在時刻
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init] ;
    [dateFormatter setDateFormat:@"MMMM. dd,yyyy"] ;
    NSString *dateString = [dateFormatter stringFromDate:date] ;
    
    [self outputResult:dateString] ; // 結果出力用
}

月を January February などの英語表記にした文字列の出力結果

NSDateFormatter_1_676

 

タイムゾーン表記を含めた文字列を取得するサンプル

タイムゾーン(標準時からの時差)を含めた文字列を取得する場合は z を指定します。

- (void)sampleNSDateFormatterYYYYMMDDHHMMSSWithTimezone
{
    NSDate *date = [NSDate date] ; // 現在時刻
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init] ;
    [dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss z"] ;
    NSString *dateString = [dateFormatter stringFromDate:date] ;
    
    [self outputResult:dateString] ; // 結果出力用
}

タイムゾーン表記を含めた文字列の出力結果

NSDateFormatter_1_896

UILabel 文字の大きさを変更する

UILabel を使って文字列を表示する際の文字の大きさは setFont で文字サイズの値を持つ UIFont のインスタンスを指定して行います。

フォントの種類はそのままで文字サイズだけ変更したい場合は UIFont の fontWithSize を使って種類はそのままでサイズだけ変更した UIFont のインスタンスを生成して使います。

フォントサイズ16 サンプル

- (void)sampleUILabelSetFontSystemFont16
{
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setText:@"Sample Font Size Text 16.0"] ;
    [label setFont:[UIFont systemFontOfSize:16.0]] ;
    [self.view addSubview:label] ;
}

フォントサイズ16 表示結果

UILabel_3_798

フォントサイズ24 サンプル

- (void)sampleUILabelSetFontSystemFont24
{
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setText:@"Sample Font Size Text 24.0"] ;
    [label setFont:[UIFont systemFontOfSize:24.0]] ;
    [self.view addSubview:label] ;
}

フォントサイズ24 表示結果

UILabel_4_676

サイズのみ変更 サンプル

- (void)sampleUILabelSetFontSize12
{
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setText:@"Sample Font Size Text 12.0"] ;
    [label setFont:[label.font fontWithSize:12.0]] ;
    [self.view addSubview:label] ;
}

 サイズのみ変更 表示結果

UILabel_4_896

UILabel 行間を調整する

UILabel を使って複数行の文字列を表示する際の行間を調整する場合は NSAttributedString を使って一行の高さを指定して調整します。

NSMutableParagraphStyle のインスタンスに setMinimumLineHeight と setMaximumLineHeight で行の高さを指定し、それを元に NSAttributedString を生成して UILabel に指定します。

行の高さ16 サンプル

- (void)sampleUILabelSetAttributedTextLineHeight16
{
    CGFloat lineHeight = 16.0 ;
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init] ;
    [paragraphStyle setMinimumLineHeight:lineHeight] ;
    [paragraphStyle setMaximumLineHeight:lineHeight] ;

    NSString *string = @"Sample Specific Line Height Text 16.0 Sample Specific Line Height Text 16.0 Sample Specific Line Height Text 16.0" ;
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:paragraphStyle,NSParagraphStyleAttributeName,nil] ;
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string attributes:attributes] ;

    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setNumberOfLines:3] ;
    [label setAttributedText:attributedText] ;
    [self.view addSubview:label] ;
}

行の高さ16 表示結果

UILabel_3_358

行の高さ24 サンプル

- (void)sampleUILabelSetAttributedTextLineHeight24
{
    CGFloat lineHeight = 24.0 ;
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init] ;
    [paragraphStyle setMinimumLineHeight:lineHeight] ;
    [paragraphStyle setMaximumLineHeight:lineHeight] ;

    NSString *string = @"Sample Specific Line Height Text 24.0 Sample Specific Line Height Text 24.0 Sample Specific Line Height Text 24.0" ;
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:paragraphStyle,NSParagraphStyleAttributeName,nil] ;
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:string attributes:attributes] ;

    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setNumberOfLines:3] ;
    [label setAttributedText:attributedText] ;
    [self.view addSubview:label] ;
}

行の高さ24 表示結果

UILabel_3_578

UILabel 文字と文字の間隔を変更する

UILabel で文字と文字の間隔を変更する場合は NSAttributedString という属性付き文字列クラスを使います。

NSKernAttributeName をキーに、文字間隔を値にした Dictionary を作成して、NSAttributedString を生成します。(文字間隔はデフォルトからの差分)

生成した NSAttributedString をUILabel に setAttributedText で設定すると、文字間隔を調整した文字列が表示されます。

文字間隔 ±0 サンプル

- (void)sampleUILabelSetAttributedTextKerning0
{
    NSString *stringToBeKerned = @"Sample Kerning Text" ;
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:0.0],NSKernAttributeName,nil] ;
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:stringToBeKerned attributes:attributes] ;

    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setAttributedText:attributedText] ;
    [self.view addSubview:label] ;
}

文字間隔 ±0 表示結果

文字間隔に ±0 を指定して表示した結果です。普通ですね。

UILabel_2_580

文字間隔 +4.0 サンプル

- (void)sampleUILabelSetAttributedTextKerningPlus4
{
    NSString *stringToBeKerned = @"Sample Kerning Text +4.0" ;
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:4.0],NSKernAttributeName,nil] ;
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:stringToBeKerned attributes:attributes] ;

    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setAttributedText:attributedText] ;
    [self.view addSubview:label] ;
}

文字間隔 +4.0 表示結果

文字間隔に +4.0 を指定して表示した結果です。

0 のときに比べてかなり間隔が長くなりました。

UILabel_2_800

文字間隔 -2.0 サンプル

- (void)sampleUILabelSetAttributedTextKerningMinus2
{
    NSString *stringToBeKerned = @"Sample Kerning Text -2.0" ;
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:-2.0],NSKernAttributeName,nil] ;
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:stringToBeKerned attributes:attributes] ;

    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setAttributedText:attributedText] ;
    [self.view addSubview:label] ;
}

文字間隔 -2.0 表示結果

文字間隔に -2.0 を指定して表示した結果です。

文字間がほぼ無く、くっついて見えます。

UILabel_3_138

UILabel の文字を左揃え、中央揃え、右揃え、両端揃え、で表示する

UILabel で文字列を表示する場合は setTextAlignment を使って、左、中央、右に文字列を表示できます。

また、両端を揃えたい場合は NSAttributedString という属性付き文字列を指定して表示することで可能です。

左詰めサンプル

文字列を左側に揃える場合は setTextAlignment にNSTextAlignmentLeft を指定します。

ちなみに、何も指定しない状態(デフォルト)だと NSTextAlignmentLeft で表示されるようです。

- (void)sampleUILabelSetTextAlignmentLeft
{
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setText:@"Sample Left Text"] ;
    [label setTextAlignment:NSTextAlignmentLeft] ;
    [self.view addSubview:label] ;
}

 左詰め表示結果

NSTextAlignmentLeft を指定して表示した結果です。

UILabel_1_606

中央サンプル

文字列を中央に揃える場合は setTextAlignment にNSTextAlignmentCenterを指定します。

- (void)sampleUILabelSetTextAlignmentCenter
{
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setText:@"Sample Center Text"] ;
    [label setTextAlignment:NSTextAlignmentCenter] ;
    [self.view addSubview:label] ;
}

中央表示結果

NSTextAlignmentCenter を指定して表示した結果です。

UILabel_1_826

右詰めサンプル

文字列を右側に揃える場合は setTextAlignment にNSTextAlignmentRightを指定します。

- (void)sampleUILabelSetTextAlignmentRight
{
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setText:@"Sample Right Text"] ;
    [label setTextAlignment:NSTextAlignmentRight] ;
    [self.view addSubview:label] ;
}

右詰め表示結果

NSTextAlignmentRightを指定して表示した結果です。

UILabel_2_140

両端揃えサンプル

文字列の両端を揃える場合は NSAttributedString という属性付き文字列を使用します。

まずは NSMutableParagraphStyle というクラスのインスタンスを生成して setAlignment に NSTextAlignmentJustified を指定します。

また setFirstLineHeadIndent で最初の行のインデントを指定します。

setFirstLineHeadIndent を指定しなかったり、0 を指定したりするとなぜか両端揃えになりません。インデントを設定したくない場合は 0.01 などの小さな値を指定して実質 0 の状態にしておきましょう。

その後、NSMutableParagraphStyle  を指定して  NSAttributedString を生成します。

そして生成した NSAttributedString を UILabel の setAttributedText で指定すれば両端揃えで表示されます。

- (void)sampleUILabelSetAttributedTextJustified
{
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init] ;
    [paragraphStyle setAlignment:NSTextAlignmentJustified] ;
    [paragraphStyle setFirstLineHeadIndent:0.01] ;
    
    NSString *stringToBeJustified = @"Sample Justified Text Sample Justified Text Sample Justified Text Sample Justified Text" ;
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:paragraphStyle,NSParagraphStyleAttributeName,nil] ;
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:stringToBeJustified attributes:attributes] ;
    
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setNumberOfLines:3] ;
    [label setBackgroundColor:[UIColor grayColor]] ;
    [label setAttributedText:attributedText] ;
    [self.view addSubview:label] ;
}

両端揃え表示結果

NSAttributedString を指定して表示した結果です。

一行目の単語の間の幅と、二行目の単語の間の幅が違うのがわかると思います。

単語の間の幅を自動的に調整して両端が揃うようになっています。

UILabel_2_360

UILabel の文字色を指定する

UILabel で表示する文字の色を変更する場合は setTextColor を使って色を指定します。

setTextColor に 色を表す UIColor のインスタンスを渡します。

サンプル

文字色として赤を指定して表示するサンプルです。

- (void)sampleUILabelSetTextColor
{
    UILabel *label = [[UILabel alloc] initWithFrame:viewFrame] ;
    [label setText:@"Sample Red Text"] ;
    [label setTextColor:[UIColor redColor]] ;
    [self.view addSubview:label] ;
}

 表示結果

指定した赤色で表示されました。

UILabel_1_386