Mac Appはi 18 nとMirroringをサポート


この記事では、Macアプリケーションがアラビア語サポートプロジェクトで発生した問題をまとめました.
必要:
  • Mac用に開発されたアプリケーションがあります.
  • ハングル、英語、アラビア語をサポートする必要があります.
  • Mac OSの言語設定は、アプリケーション内の言語設定ではなく、アプリケーションの使用言語を変更する必要があります.
  • アプリケーションの言語設定に基づいて言語を変更するのはそれほど難しくありません.言語別にリソースファイルを作成し、対応するキーワード文字列をTextFieldまたはLabelに挿入できます.
    in Locale-ko.strings
    "Confirm" = "확인";
    
    in Locale-en.strings
    "Confirm" = "OK";
    
    self.okButton.title = [[NSBundle mainBundle] localizedStringForKey:@"Confirm" value:nil table:@"Locale-en"];
    アラビア語は同じように応用すればいい.しかし、問題はアラビア語が右から左にマークされているため、既存の左揃えを右揃えに変更する必要があり、画面上のすべてのコントロールも左揃えに変更する必要があります.
    必要な画面を言語別に表示する2つの画面を用意するだけでいいですが、既存の開発アプリケーションに適用するには時間がかかります.
    iOSのUIViewでは、意味ContentAttributeによってアプリケーションを簡略化できます.次のリンクを参照してください.
    https://medium.com/if-let-swift-programming/working-with-localization-in-swift-4a87f0d393a4
    残念なことに、NSViewは意味ContentAttributeをサポートしていません.NSViewはuserInterfaceLayoutDirectionを使用する必要があります.
    1つの問題は、UIVEの意味ContentAttributがUIをすぐに変更し、NSViewのユーザーインタフェースLayoutDirectionはすぐに変更しないことです.
    言語変更時にアプリケーションを再起動する必要はありませんが、すぐに反映する必要がある場合は、次のコードを参照してください.
    - (IBAction)btnClicked:(id)sender {
    
        AppDelegate *appDelegate = [NSApplication sharedApplication].delegate;
        NSUserInterfaceLayoutDirection direction;
        if (appDelegate.isLayoutMode) {
            direction = NSUserInterfaceLayoutDirectionLeftToRight;
        } else {
            direction = NSUserInterfaceLayoutDirectionRightToLeft;
        }
        self.view.userInterfaceLayoutDirection = direction;
        
        [self setDirection:self.view withDirection:direction];
    
        appDelegate.isLayoutMode = !appDelegate.isLayoutMode;
        
        NSView *parent = self.view.superview;
        [self.view removeFromSuperview];
        [parent addSubview:self.view]; //reloads the view from the nib//
    }
    
    - (void)setDirection:(NSView *)view withDirection:(NSUserInterfaceLayoutDirection)direction
    {
        NSArray *subviews = [view subviews];
        for (NSView *subview in subviews) {
            subview.userInterfaceLayoutDirection = direction;
            if ([subview isKindOfClass:[NSTextField class]]) {
                NSLog(@"NSTextField");
                NSTextField *textField = (NSTextField *)subview;
                textField.alignment = !textField.alignment;
            } else if ([subview isKindOfClass:[NSImageView class]]) {
                NSLog(@"NSImageView");
                NSImageView *imageView = (NSImageView *)subview;
                NSImage *image = imageView.image;
                imageView.image = [self flipImageHorizontally:image];
            }
            [self setDirection:subview withDirection:direction];
        }
    }
    また、上記の方法では、TableViewスクロールバーの位置は変更されません.Table ViewはCustomsColleViewを保持し、drawRectでスクロールバーを次のように変更します.
    - (void)drawRect:(NSRect)dirtyRect {
        [super drawRect:dirtyRect];
        
        // Drawing code here.
        AppDelegate *appDelegate = [NSApplication sharedApplication].delegate;
        NSRect scrollViewRect = [self frame];
        
        NSScroller *verticalScroller = [self verticalScroller];
        NSRect verticalScrollerFrame = [verticalScroller frame];
    
        NSClipView *clipView = [self contentView];
        NSRect clipViewFrame = [clipView frame];
    
        if (appDelegate.isLayoutMode) {
            verticalScrollerFrame.origin.x = scrollViewRect.size.width - verticalScrollerFrame.size.width - 1;
            clipViewFrame.origin.x = 1.0;
            NSLog(@"CustomScrollView isLeftToRight");
        } else {
            verticalScrollerFrame.origin.x = 1.0;
            /*
             OS 일반설정에서 스크롤 막대 보기 설정에 따라 "항상"이 아닌 경우에는 스크롤 width 가 전체 width 에 공간을 차지하지 않는다.
             설정값을 확인하는 방법은 스크롤이 hidden 되지 않았을 때 scrollView의 width와 clipView의 width 가 2보다 크면 "항상"으로 설정된 것임
             차이값 2는 border 가 차지하는 것으로 보임
             */
            NSLog(@"scrollView width=%f, clipView width=%f", scrollViewRect.size.width, clipViewFrame.size.width);
            if (!verticalScroller.isHidden && (scrollViewRect.size.width - clipViewFrame.size.width) > 2) {
                clipViewFrame.origin.x = verticalScrollerFrame.size.width + 1;
            }
            NSLog(@"CustomScrollView isRightToLeft");
        }
    
        [verticalScroller setFrame:verticalScrollerFrame];
    
        [clipView setFrame:clipViewFrame];
        [self setVerticalScroller:verticalScroller];
    }
    サンプルコードリンクhttps://github.com/panicstyle/MirroringSample