2012-12-04 28 views
6

Tôi thấy một UIActionSheet như thế này:UIActionSheet showFromRect autorotation

-(void)accessoryPressed:(id)sender{ 
    //Omitted unnecessary objects 

    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:titleString delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:@"Upload", nil]; 
    //actionSheet.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; 
    actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent; 
    actionSheet.tag = ((UIButton*)sender).tag; 
    [actionSheet showFromRect:[(UIButton*)sender frame] inView:[(UIButton*)sender superview] animated:YES]; 
} 

Trường hợp đối tượng sender là một UIButton nhúng vào trong một cái nhìn phụ kiện UITableViewCell 's.

Vấn đề là khi iPad được xoay bảng tác vụ không thay đổi kích thước (tôi không mong nó thực sự RESIZE nhưng tôi muốn nó ở đúng X, Y) Tôi đã thử đặt AutoResizingMask thành FlexibleLeft và FlexibleTop nhưng nó dường như không thay đổi.

Có ai có ý tưởng nào về cách tải ActionSheet để trỏ đến số accessoryView sau khi tự động xoay không?

Đây là những gì nó trông giống như:

Trước Rotation- Before Rotation

Sau Rotation - enter image description here

Trả lời

7

Đó là một sự xấu hổ UIKit không xử lý đúng đắn này cho chúng tôi. Trong ứng dụng của riêng tôi, tôi xử lý việc này bằng cách triển khai phương thức didRotateFromInterfaceOrientation: trong trình điều khiển chế độ xem của tôi và chỉnh sửa lại bất kỳ cửa sổ bật lên nào bằng cách sử dụng khung được cập nhật của chế độ xem.

+0

Ok, tôi đoán đó là những gì tôi sẽ phải để làm sau đó. Nó có thể là tốt đẹp để có nó sinh động cho nút xy mới. Cảm ơn. – mkral

+0

'willRotateToInterfaceOrientation' cho kết quả tốt hơn để xử lý trường hợp này. –

0

Giải pháp của tôi cho điều này là một biến thể tổng quát về @ rmaddy's. Đó là một chút phức tạp, nhưng nếu bạn muốn có một giải pháp chung để nhận được callbacks cho luân chuyển, điều này có thể giúp đỡ. Tôi có một bộ điều khiển xem chứa chính (nếu bạn muốn, suy nghĩ về điều này như một lớp con của UINavigationController) trong đó tôi thực hiện:

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; 
{ 
    [[SMRotation session] viewControllerWillRotate]; 
} 

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation; 
{ 
    [[SMRotation session] viewControllerDidRotate]; 
} 

Trong các lớp học mà tôi cần nó (thường không xem lớp điều khiển), tôi đăng ký gọi lại. Ví dụ:

[[SMRotation session].willRotate addTarget:popTip withSelector:@selector(willRotateHelp)]; 
[[SMRotation session].didRotate addTarget:popTip withSelector:@selector(didRotateHelp)]; 

Lớp SMRotation là như sau:

// 
// SMRotation.h 
// Petunia 
// 
// Created by Christopher Prince on 5/10/15. 
// Copyright (c) 2015 Spastic Muffin, LLC. All rights reserved. 
// 

// The reason for this class is because I don't, in general, appear to be able to get willRotate notifications from iOS. UIDevice only seems to support didRotate notifications. 

#import <Foundation/Foundation.h> 
#import "NSObject+TargetsAndSelectors.h" 

@interface SMRotation : NSObject 

+ (instancetype) session; 

// Call these back from the same named methods in your main view controller. 
- (void) viewControllerWillRotate; 
- (void) viewControllerDidRotate; 

// Use these in other classes to get rotation callbacks. There are no parameters passed to the callbacks. 
@property (nonatomic, strong, readonly) NSObject<TargetsAndSelectors> *willRotate; 
@property (nonatomic, strong, readonly) NSObject<TargetsAndSelectors> *didRotate; 

@end 

// 
// SMRotation.m 
// Petunia 
// 
// Created by Christopher Prince on 5/10/15. 
// Copyright (c) 2015 Spastic Muffin, LLC. All rights reserved. 
// 

#import "SMRotation.h" 

@interface SMRotation() 
@property (nonatomic, strong) NSObject<TargetsAndSelectors> *willRotate; 
@property (nonatomic, strong) NSObject<TargetsAndSelectors> *didRotate; 
@end 

@implementation SMRotation 

+ (instancetype) session; 
{ 
    static SMRotation* s_sharedInstance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     s_sharedInstance = [self new]; 
     [s_sharedInstance setup]; 
    }); 

    return s_sharedInstance; 
} 

- (void) setup; 
{ 
    self.willRotate = [NSObject new]; 
    [self.willRotate resetTargets]; 
    self.didRotate = [NSObject new]; 
    [self.didRotate resetTargets]; 
} 

- (void) viewControllerWillRotate; 
{ 
    [self.willRotate forEachTargetInCallbacksDo:^(id target, SEL selector, NSMutableDictionary *dict) { 
     [target performVoidReturnSelector:selector]; 
    }]; 
} 

- (void) viewControllerDidRotate; 
{ 
    [self.didRotate forEachTargetInCallbacksDo:^(id target, SEL selector, NSMutableDictionary *dict) { 
     [target performVoidReturnSelector:selector]; 
    }]; 
} 

@end 

Phạm trù TargetsAndSelectors được như sau:

// 
// NSObject+TargetsAndSelectors.h 
// Petunia 
// 
// Created by Christopher Prince on 5/11/15. 
// Copyright (c) 2015 Spastic Muffin, LLC. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

// Allow an object to have a collection of target's, and selectors that can be called as needed. 

@protocol TargetsAndSelectors <NSObject> 

// The only reason I have made all of these optional is to avoid the compiler complaining. I'm using this protocol just to document the fact that I'm making these methods available (through the NSObject (TargetsAndSelectors) category) in a particular class. 
@optional 

// Clear all target/selector's. This method must be called *before* any call to addTarget or to other methods of this category, for a particular instance. 
- (void) resetTargets; 

/** 
* Add/remove a callback. 
* 
* @param target Target object. 
* @param selector Method to call on the target object. 
* 
* @return Dictionary that was just added to the callbacks property for this target and selector. 
*/ 
- (NSMutableDictionary *) addTarget: (id) target withSelector: (SEL) selector; 
- (void) removeTarget: (id) target withSelector: (SEL) selector; 

/** 
* Convenience method to enable calling each of the callbacks in sequence. 
*/ 
- (void) forEachTargetInCallbacksDo: (void (^)(id target, SEL selector, NSMutableDictionary *dict)) block; 

// Elements are NSMutableDictionary's, with keys: 
// Value of this is a target (id) embedded in a WeakRef object, so that if the target is deallocated, we don't retain a reference that object. 
#define TARGETS_KEY_WEAK_TARGET @"weakTarget" 
// Value of this is formatted as an NSString 
#define TARGETS_KEY_SELECTOR @"selector" 
@property (nonatomic, strong, readonly) NSArray *callbacks; 

@end 

@interface NSObject (TargetsAndSelectors)<TargetsAndSelectors> 
@end 

012.351.
// 
// NSObject+TargetsAndSelectors.m 
// Petunia 
// 
// Created by Christopher Prince on 5/11/15. 
// Copyright (c) 2015 Spastic Muffin, LLC. All rights reserved. 
// 

#import "NSObject+TargetsAndSelectors.h" 
#import <objc/runtime.h> 
#import "WeakRef.h" 

@implementation NSObject (TargetsAndSelectors) 

static char kCallbacksKey; 

- (void) setCallbacks:(NSArray *)callbacks 
{ 
    objc_setAssociatedObject(self, &kCallbacksKey, callbacks, OBJC_ASSOCIATION_RETAIN); 
} 

- (NSArray *) callbacks 
{ 
    NSArray *theCallbacks = (NSArray *) objc_getAssociatedObject(self, &kCallbacksKey); 
    return theCallbacks; 
} 

- (void) resetTargets 
{ 
    self.callbacks = [NSMutableArray new]; 
} 

- (NSMutableArray *) mutableCallbacks 
{ 
    NSMutableArray *mutableCallbacks = (NSMutableArray *) self.callbacks; 
    return mutableCallbacks; 
} 

- (NSMutableDictionary *) addTarget: (id) target withSelector: (SEL) selector; 
{ 
    WeakRef *weakTarget = [WeakRef toObj:target]; 

    NSMutableDictionary *dict = [@{TARGETS_KEY_WEAK_TARGET: weakTarget, 
            TARGETS_KEY_SELECTOR: NSStringFromSelector(selector)} mutableCopy]; 
    [[self mutableCallbacks] addObject:dict]; 
    return dict; 
} 

- (void) removeTarget: (id) target withSelector: (SEL) selector; 
{ 
    NSString *stringSelector = NSStringFromSelector(selector); 
    NSDictionary *dictToRemove = nil; 

    for (NSDictionary *dict in [self mutableCallbacks]) { 
     NSString *dictSelectorString = dict[TARGETS_KEY_SELECTOR]; 
     WeakRef *weakTarget = dict[TARGETS_KEY_WEAK_TARGET]; 
     if (weakTarget.obj == target && [dictSelectorString isEqualToString:stringSelector]) { 
      dictToRemove = dict; 
      break; 
     } 
    } 

    if (dictToRemove) { 
     [[self mutableCallbacks] removeObject:dictToRemove]; 
    } 
} 

- (void) forEachTargetInCallbacksDo: (void (^)(id target, SEL selector, NSMutableDictionary *dict)) block; 
{ 
    // 5/10/15; Making a copy of the callbacks array in case one of the callbacks calls removeTarget above. 
    NSArray *copyOfCallbacks = [self.callbacks copy]; 

    for (NSMutableDictionary *dict in copyOfCallbacks) { 
     NSString *dictSelectorString = dict[TARGETS_KEY_SELECTOR]; 
     SEL selector = NSSelectorFromString(dictSelectorString); 

     WeakRef *weakTarget = dict[TARGETS_KEY_WEAK_TARGET]; 

     // Going to just skip by any target that is nil, i.e., has been deallocated. A better idea would be to remove that target from the array... 
     if (weakTarget.obj) { 
      block(weakTarget.obj, selector, dict); 
     } 
    } 
} 

@end 

Cuối cùng, WeakRef là:

// 
// WeakRef.h 
// Petunia 
// 
// Created by Christopher Prince on 9/1/14. 
// Copyright (c) 2014 Spastic Muffin, LLC. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

@interface WeakRef : NSObject 

+ (instancetype) toObj: (id) obj; 
+ (id) from: (WeakRef *) weakRef; 

@property (nonatomic, weak) id obj; 

@end 

// 
// WeakRef.m 
// Petunia 
// 
// Created by Christopher Prince on 9/1/14. 
// Copyright (c) 2014 Spastic Muffin, LLC. All rights reserved. 
// 

#import "WeakRef.h" 

@implementation WeakRef 

+ (instancetype) toObj: (id) obj; 
{ 
    WeakRef *result = [WeakRef new]; 
    result.obj = obj; 
    return result; 
} 

+ (id) from: (WeakRef *) weakRef; 
{ 
    return weakRef.obj; 
} 

@end 

Đoán một số điều này nên đi trên Github ...

Các vấn đề liên quan