창에서 UIBarButtonItem 프레임을 알아 내십니까?
UIBarButtonItem
확장되지 않으므로 UIView
프레임 속성과 같은 것은 없습니다.
그러나 CGRect
응용 프로그램과 관련하여 프레임 이 무엇인지 얻을 수있는 방법이 UIWindow
있습니까?
비공개 API 를 사용 하시겠습니까? 경우 예,
UIView* view = thatItem.view;
return [view convertRect:view.bounds toView:nil];
물론 AppStore를 대상으로 할 때 아무도 이것을 원하지 않습니다. 더 신뢰할 또한 방법 및 문서화되지 않은 기능을 사용하지만, 애플의 테스트를 통과합니다, 해당 버튼 항목을 찾기 위해 파단을 반복하는 것입니다.
NSMutableArray* buttons = [[NSMutableArray alloc] init];
for (UIControl* btn in theToolbarOrNavbar.subviews)
if ([btn isKindOfClass:[UIControl class]])
[buttons addObject:btn];
UIView* view = [buttons objectAtIndex:index];
[buttons release];
return [view convertRect:view.bounds toView:nil];
는 index
배열에 막대 항목의 인덱스 .items
, 모든 빈 항목을 제거한 후 . 이것은 버튼이 오름차순으로 정렬되어 있다고 가정 합니다. 보다 안정적인 방법은 증가하는 값으로 배열 을 정렬 하는 것 입니다. 물론 이것은 여전히 바 버튼 항목이 UIControl 클래스를 상속 받아야하고 툴바 / 내비게이션 바의 직접적인 서브 뷰 라고 가정 합니다.buttons
.origin.x
보시다시피 문서화되지 않은 기능을 다룰 때 많은 불확실성이 있습니다. 그러나 손가락 아래에 무언가를 팝업하고 싶습니까? UIBarButtonItem .action
은 다음 형식의 선택자가 될 수 있습니다.
-(void)buttonClicked:(UIBarButtonItem*)sender event:(UIEvent*)event;
이벤트 인수에 주의하십시오 — 당신은 접촉의 위치를 얻을 수 있습니다
[[event.allTouches anyObject] locationInView:theWindow]
또는 버튼보기
[[event.allTouches anyObject] view]
따라서 원하는 작업을 위해 하위보기를 반복하거나 문서화되지 않은 기능을 사용할 필요가 없습니다.
이 옵션이 게시 된 것을 보지 못했기 때문에 (제 생각에는 훨씬 더 간단합니다) 여기에 있습니다.
UIView *barButtonView = [barButtonItem valueForKey:@"view"];
iOS 3.2에는 툴바 버튼에서 액션 시트 팝 오버를 표시하는 훨씬 더 쉬운 방법이 있습니다. 다음과 같이하세요.
- (IBAction)buttonClicked:(UIBarButtonItem *)sender event:(UIEvent *)event
{
UIActionSheet *popupSheet;
// Prepare your action sheet
[popupSheet showFromBarButtonItem:sender animated:YES];
}
이것은 내 WEPopover 프로젝트에 사용하는 구현입니다 : ( https://github.com/werner77/WEPopover ) :
@implementation UIBarButtonItem(WEPopover)
- (CGRect)frameInView:(UIView *)v {
UIView *theView = self.customView;
if (!theView.superview && [self respondsToSelector:@selector(view)]) {
theView = [self performSelector:@selector(view)];
}
UIView *parentView = theView.superview;
NSArray *subviews = parentView.subviews;
NSUInteger indexOfView = [subviews indexOfObject:theView];
NSUInteger subviewCount = subviews.count;
if (subviewCount > 0 && indexOfView != NSNotFound) {
UIView *button = [parentView.subviews objectAtIndex:indexOfView];
return [button convertRect:button.bounds toView:v];
} else {
return CGRectZero;
}
}
@end
긴만큼 UIBarButtonItem
(그리고 UITabBarItem
상속하지 않습니다) UIView
-for 역사적 이유 UIBarItem
에서 상속 NSObject
-이 막무가내 (...이 글을 쓰는, 아이폰 OS 8.2 및 계산 기준) 계속
이 스레드의 가장 좋은 대답은 분명히 @ KennyTM 's 입니다. 바보처럼 굴지 말고 비공개 API를 사용하여보기를 찾으세요.
다음은 origin.x
정렬 된 배열 을 얻는 한 줄 Swift 솔루션입니다 ( Kenny의 답변이 제안한 것처럼).
let buttonFrames = myToolbar.subviews.filter({
$0 is UIControl
}).sorted({
$0.frame.origin.x < $1.frame.origin.x
}).map({
$0.convertRect($0.bounds, toView:nil)
})
이제 배열이 프레임 origin.x
으로 정렬됩니다 UIBarButtonItem
.
(UIBarButtonItem에 대한 다른 사람들의 어려움에 대해 더 많이 읽을 필요가 있다고 느낀다면 2012 년 Ash Furrow의 블로그 게시물 : Exploring UIBarButtonItem을 추천합니다. )
UIBarButton 과 함께 툴바를 전달하여 Werner Altewischer의 WEpopover를 작동시킬 수있었습니다 . Mod는 WEPopoverController.m에 있습니다.
- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item toolBar:(UIToolbar *)toolBar
permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections
animated:(BOOL)animated
{
self.currentUIControl = nil;
self.currentView = nil;
self.currentBarButtonItem = item;
self.currentArrowDirections = arrowDirections;
self.currentToolBar = toolBar;
UIView *v = [self keyView];
UIButton *button = nil;
for (UIView *subview in toolBar.subviews)
{
if ([[subview class].description isEqualToString:@"UIToolbarButton"])
{
for (id target in [(UIButton *)subview allTargets])
{
if (target == item)
{
button = (UIButton *)subview;
break;
}
}
if (button != nil) break;
}
}
CGRect rect = [button.superview convertRect:button.frame toView:v];
[self presentPopoverFromRect:rect inView:v permittedArrowDirections:arrowDirections animated:animated];
}
-(CGRect) getBarItemRc :(UIBarButtonItem *)item{
UIView *view = [item valueForKey:@"view"];
return [view frame];
}
UINavigationBar보기에서 가져올 수 있습니다. navigationBar는 바의 파트에 대해 2 개 또는 3 개의 사용자 지정 하위보기 가있는 UIView입니다 .
UIBarButtonItem이 현재 오른쪽의 navbar에 표시되는 것을 알고 있다면 navbar의 subviews 배열에서 프레임을 가져올 수 있습니다.
먼저 UIViewController에서 얻을 수 있는 navigationController 에서 얻을 수 있는 navigationBar 가 필요합니다 . 그런 다음 가장 적합한 하위보기를 찾습니다.
UINavigationBar* navbar = curViewController.navigationController.navigationBar;
UIView* rightView = nil;
for (UIView* v in navbar.subviews) {
if (rightView==nil) {
rightView = v;
} else if (v.frame.origin.x > rightView.frame.origin.x) {
rightView = v; // this view is further right
}
}
// at this point rightView contains the right most subview of the navbar
이 코드를 YMMV로 컴파일하지 않았습니다.
이것은 최선의 해결책이 아니며 어떤 관점에서 보면 올바른 해결책이 아니며 UIBarBattonItem
암시 적으로 내부 객체에 액세스하기 때문에 따르기를 좋아할 수 없지만 다음과 같은 작업 을 시도 할 수 있습니다.
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[button setImage:[UIImage imageNamed:@"Menu_Icon"] forState:UIControlStateNormal];
[button addTarget:self action:@selector(didPressitem) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.rightBarButtonItem = item;
CGPoint point = [self.view convertPoint:button.center fromView:(UIView *)self.navigationItem.rightBarButtonItem];
//this is like view because we use UIButton like "base" obj for
//UIBarButtonItem, but u should note that UIBarButtonItem base class
//is NSObject class not UIView class, for hiding warning we implicity
//cast UIBarButtonItem created with UIButton to UIView
NSLog(@"point %@", NSStringFromCGPoint(point));
결과적으로 다음을 얻었습니다.
포인트 {289, 22}
Before implement this code, be sure to call [window makeKeyAndVisible]
in your Applition delegate application:didFinishLaunchingWithOptions:
method!
- (void) someMethod
{
CGRect rect = [barButtonItem convertRect:barButtonItem.customview.bounds toView:[self keyView]];
}
- (UIView *)keyView {
UIWindow *w = [[UIApplication sharedApplication] keyWindow];
if (w.subviews.count > 0) {
return [w.subviews objectAtIndex:0];
} else {
return w;
}
}
I handled it as follows:
- (IBAction)buttonClicked:(UIBarButtonItem *)sender event:(UIEvent *)event
{
UIView* view = [sender valueForKey:@"view"]; //use KVO to return the view
CGRect rect = [view convertRect:view.bounds toView:self.view];
//do stuff with the rect
}
참고URL : https://stackoverflow.com/questions/2994354/figure-out-uibarbuttonitem-frame-in-window
'UFO ET IT' 카테고리의 다른 글
전역 변수를 사용하지 않고 다른 함수의 변수에 액세스 (0) | 2020.11.19 |
---|---|
SQL Server에서 밀리 초가 손실되는 이유는 무엇입니까? (0) | 2020.11.19 |
React Native에서 텍스트 입력을 올바르게 정렬하는 방법은 무엇입니까? (0) | 2020.11.19 |
laravel 설치 프로그램을 사용하여 특정 버전 설치 (0) | 2020.11.19 |
NSData를 파일에 쓰는 가장 쉬운 방법 (0) | 2020.11.19 |