Development Tip

UIToolBar 왼쪽 및 오른쪽 패딩 조정 방법

yourdevel 2020. 12. 2. 22:04
반응형

UIToolBar 왼쪽 및 오른쪽 패딩 조정 방법


코드로 하나의 UIToolbar를 만들고 인터페이스 빌더로 다른 하나를 만듭니다. 그러나 아래에 표시된 왼쪽 및 오른쪽 패딩이 다른 두 도구 모음을 발견했습니다.

Interface Builder에서 :

여기에 이미지 설명 입력

코드에서 :

여기에 이미지 설명 입력

UIImage *buttonImage = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];
UIButton *btnTest = [UIButton buttonWithType:UIButtonTypeCustom];
[btnTest setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnTest setTitle:@"Back" forState:UIControlStateNormal];   
[btnTest.titleLabel setFont:[UIFont boldSystemFontOfSize:13]];  
[btnTest setBackgroundImage:[imgToolbarButton stretchableImageWithLeftCapWidth:5 topCapHeight:0]  forState:UIControlStateNormal];
[btnTest addTarget:self action:@selector(clearDateEdit:) forControlEvents:UIControlEventTouchUpInside];
btnTest.frame = CGRectMake(0.0, 0.0, 50, 30);
UIBarButtonItem *btnTestItem = [[UIBarButtonItem alloc] initWithCustomView:btnTest];
[self.toolbar setItems:[NSArray arrayWithObjects:btnTestItem,nil]];
[btnTestItem release];

내 질문은 코드로 UIToolbar의 왼쪽 및 오른쪽 패딩을 어떻게 조정할 수 있습니까?

최신 정보

이 정렬 문제는 UIButton의 customView가있는 UIBarButtonItem에서만 발생한다는 것을 발견했습니다. UIBarButtonItem에서는 정렬이 괜찮습니다. 원인이 무엇인지 또는이를 해결했는지 알 수 있습니다.

지금 생각할 수있는 유일한 해결책은 프레임을 수동으로 설정하는 것입니다.


나는 같은 문제가 있었고 UIBarButtonSystemItemFixedSpace로 할 수있는 깔끔한 트릭이 있습니다. 첫 번째 버튼 앞과 마지막 버튼 뒤에 음수 너비를 추가하면 버튼이 가장자리로 이동합니다.

예를 들어 오른쪽 여백을 제거하려면 다음 FixedSpace 막대 항목을 마지막 항목으로 추가합니다.

UIBarButtonItem *negativeSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSeparator.width = -12;

왼쪽과 오른쪽의 여백은 12px입니다.

iOS7 업데이트-여백은 iPhone에서 16px, iPad에서 20px입니다!


iOS 11 이전

세 가지 가능한 솔루션이 있습니다.

  • 첫 번째는 너비가 음수 인 고정 공간 항목 UIBarButtonItem (barButtonSystemItem : .fixedSpace…)을 사용했습니다.
  • 다른 하나는 사용자 정의 뷰에서 alignmentRectInsets를 재정의하는 것입니다.
  • 마지막 항목은 UIButton을 항목의 사용자 정의보기로 사용하는 경우 contentEdgeInsets 및 hitTest (_ : with :)를 재정의 할 수 있습니다.

당연히 첫 번째 해결책은 다른 것보다 더 나은 것 같습니다

UIBarButtonItem *negativeSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSeparator.width = -12;

스위프트를 사용하면 코드는 다음과 같습니다.

var negativeSeparator = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
negativeSeparator.width = -12

iOS 11 이후 (iOS 11 포함)

불행히도 모든 솔루션은 iOS 11에서 사용할 수 없습니다.

  • 첫 번째 해결책 : 음수 너비 설정이 더 이상 작동하지 않음
  • 두 번째 솔루션 : alignmentRectInsets를 재정의하면 항목의 일부가 더 이상 터치를받지 못합니다.
  • 마지막 해결책 : hitTest (_ : with :) 덮어 쓰기는 좋은 생각이 아니라고 생각합니다. 제발 이렇게하지 마세요!

개발자 포럼 에서 몇 가지 제안을 볼 수도 있지만 모든 의견을 살펴본 후이 주제에 대한 제안은 사용자 지정 UINavigationBar 하위 클래스를 만들고 복잡한 작업을 수행하는 것입니다.

오 마이 갓, 내가 원하는 것은 탐색 바가 아니라 패딩을 변경하는 것입니다!

다행히 iOS 11의 트릭으로이를 수행 할 수 있습니다!

여기 우리가 간다 :

1. 사용자 정의 버튼 만들기

  • translatesAutoresizingMaskIntoConstraints를 false로 설정
  • alignmentRectInsets 재정의
    • 오른쪽 항목 사용 UIEdgeInsets (위 : 0, 왼쪽 : -8, 아래 : 0, 오른쪽 : 8)
    • 왼쪽 항목은 UIEdgeInsets (위 : 0, 왼쪽 : 8, 아래 : 0, 오른쪽 : -8)를 사용합니다.

      당신이 alignmentRectInsets을 모르는 경우, 당신이 읽을 수있는 이 블로그를 처음

신속한 버전

var customButton = UIButton(type: .custom)
customButton.overrideAlignmentRectInsets = UIEdgeInsets(top: 0, left: x, bottom: 0, right: -x) // you should do this in your own custom class
customButton.translatesAutoresizingMaskIntoConstraints = false;

Objective-c 버전

UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
customButton.overrideAlignmentRectInsets = UIEdgeInsetsMake(0, x, 0, -x); // you should do this in your own custom class
customButton.translatesAutoresizingMaskIntoConstraints = NO;

2. 사용자 정의 버튼으로 항목 만들기

신속한 버전

var item = UIBarButtonItem(customView: customButton)

Objective-c 버전

UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:customButton]

3. 양의 너비를 가진 fixedSpace 유형 UIBarButtonItem을 생성합니다.

음수 값이 아닌 양수설정

신속한 버전

var positiveSeparator = UIBarButtonItem(barButtonSystemItem:.fixedSpace, target: nil, action: nil)
positiveSeparator.width = 8

Objective-c 버전

UIBarButtonItem *positiveSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
positiveSeparator.width = 8;

4. 배열을 leftitems 또는 rightitems로 설정

fixedSpace 유형 UIBarButton 항목은 배열 첫 번째 요소 여야합니다 .

신속한 버전

self.navigationItem.leftBarButtonItems = [positiveSeparator, item, ...]

Objective-c 버전

self.navigationItem.leftBarButtonItems = @{positiveSeparator, item, ...}

잘 했어

모든 단계를 수행 한 후에는 패딩이 작아지고 입력 영역이 올바른 것 같습니다!

잘못된 점을 찾으면 알려주세요! 나는 당신의 질문에 대답하기 위해 최선을 다할 것입니다!

노트

iOS 11 이전에는 기기의 화면 너비에주의해야합니다. 화면이 5.5 인치이면 음수는 -12pt, 다른 화면에서는 -8pt입니다.

iOS 11에서 내 솔루션을 사용하는 경우 장치 화면에 신경 쓸 필요가 없습니다. 8pt 만 설정하면됩니다. 내비게이션 막대의 왼쪽 또는 오른쪽에있는 항목의 위치에 신경을 써야합니다. 이것은 사용자 정의보기의 alignmentRectInsets에 영향을줍니다.

더 많은 탭 영역을 원함

탭 영역이 44 * 44보다 크다고 약속하려면 아래 방법을 재정의 할 수 있습니다.

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    CGSize acturalSize = self.frame.size;
    CGSize minimumSize = kBarButtonMinimumTapAreaSize;
    CGFloat verticalMargin = acturalSize.height - minimumSize.height >= 0 ? 0 : ((minimumSize.height - acturalSize.height ) / 2);
    CGFloat horizontalMargin = acturalSize.width - minimumSize.width >= 0 ? 0 : ((minimumSize.width - acturalSize.width ) / 2);
    CGRect newArea = CGRectMake(self.bounds.origin.x - horizontalMargin, self.bounds.origin.y - verticalMargin, self.bounds.size.width + 2 * horizontalMargin, self.bounds.size.height + 2 * verticalMargin);
    return CGRectContainsPoint(newArea, point);
}

이것은 훌륭한 질문이며 제공된 솔루션으로도 iOS11의 문제를 해결하지 못했습니다.

작업 솔루션

의 새 확장을 만드는 경우 UIButton:

class BarButton: UIButton {

    override var alignmentRectInsets: UIEdgeInsets {
        return UIEdgeInsetsMake(0, 16, 0, 16)
    }

}

그런 다음 레이아웃에서 사용할 때 :

lazy var btnLogin: BarButton = {
    let btn = BarButton(type: .custom)
    // Add your button settings

    btn.widthAnchor.constraint(equalToConstant: self.frame.size.width).isActive = true
    btn.heightAnchor.constraint(equalToConstant: 50).isActive = true
    btn.translatesAutoresizingMaskIntoConstraints = false
    return btn
}()

이것은 매우 성가신 문제를 해결했습니다. 문제가 있으면 저에게 외쳐주세요.


이 버튼 사용

UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                                                           target:nil
                                                                           action:nil];

나는 같은 문제를 만났다. 마지막으로 UIToolbar를 서브 클래 싱하고 레이아웃 서브 뷰 메서드를 재정 의하여이 문제를 해결했습니다.

- (void)layoutSubviews {

  [super layoutSubviews];

  if (leftItem_ && leftItem_.customView
      && [leftItem_.customView isKindOfClass:[UIButton class]]) {
    CGRect newFrame = leftItem_.customView.frame;
    newFrame.origin.x = 0;   // reset the original point x to 0; default is 12, wired number
    leftItem_.customView.frame = newFrame;    
  }

  if (rightItem_ && rightItem_.customView
      && [rightItem_.customView isKindOfClass:[UIButton class]]) {
    CGRect newFrame = rightItem_.customView.frame;
    newFrame.origin.x = self.frame.size.width - CGRectGetWidth(newFrame);
    rightItem_.customView.frame = newFrame;
  }

}

You can change offset and width of your toolbar, if you want to use customview (initWithCustomView)

[myToolBar setFrame:CGRectMake(-10, 0, [UIScreen mainScreen].bounds.size.width+10, 44)];

I stumbled upon this when trying to center a toolbar as a subview of an UIButton. As the toolbar needed to be of small width, the best solution was a flexible button on each side:

UIBarButtonItem flexibleButtonItemLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

UIBarButtonItem centeredButtonItem = ...

UIBarButtonItem flexibleButtonItemRight = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

UIToolbar toolbar = ...

toolbar.items = @[flexibleButtonItemLeft, centeredButtonItem, flexibleButtonItemRight];

Finally for having customized background image for the UIBarButtonItem and to accomodate the alignment, I have abandon UIBarButtonItem and adding UIButton manually.

UIImage *buttonImage = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];
UIButton *btnTest = [UIButton buttonWithType:UIButtonTypeCustom];
[btnTest setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnTest setTitle:@"Back" forState:UIControlStateNormal];   
[btnTest.titleLabel setFont:[UIFont boldSystemFontOfSize:13]];  
[btnTest setBackgroundImage:[imgToolbarButton stretchableImageWithLeftCapWidth:5 topCapHeight:0]  forState:UIControlStateNormal];
[btnTest addTarget:self action:@selector(clearDateEdit:) forControlEvents:UIControlEventTouchUpInside];
btnTest.frame = CGRectMake(0.0, 0.0, 50, 30);
[self.toolbar addSubview:btnTest];
[btnTestItem release];

I think a tricky way is to use Aspects (or method swizzling),as blew:

[UINavigationBar aspect_hookSelector:@selector(layoutSubviews) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info){
        UINavigationBar *bar = info.instance;

        //[bar layoutSubviews];

        if ([bar isKindOfClass:[UINavigationBar class]]) {
            if (@available(iOS 11, *)) {
                bar.layoutMargins = UIEdgeInsetsZero;

                for (UIView *subview in bar.subviews) {
                    if ([NSStringFromClass([subview class]) containsString:@"ContentView"]) {
                        UIEdgeInsets oEdges = subview.layoutMargins;
                        subview.layoutMargins = UIEdgeInsetsMake(0, 0, 0, oEdges.right);
                    }
                }
            }
        }
    } error:nil];

Just add negative constants to your leading and trailing constraints of the UIToolbar. That way, the toolbar starts and ends outside of your view and therefore has less padding.

참고 URL : https://stackoverflow.com/questions/6021138/how-to-adjust-uitoolbar-left-and-right-padding

반응형