2009-07-21 16 views
12

Trong chương trình của tôi, tôi đang di chuyển mọi thứ dựa trên xoay vòng nhưng tôi không xoay toàn bộ chế độ xem. Tôi đang dùng:Tôi làm cách nào để phát hiện hướng của iPhone trước khi quay

static UIDeviceOrientation previousOrientation = UIDeviceOrientationPortrait; 

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    [window addSubview:viewController.view]; 
    [window makeKeyAndVisible]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
      selector:@selector(didRotate:) 
      name:@"UIDeviceOrientationDidChangeNotification" object:nil]; 

} 

- (void) didRotate:(NSNotification *)notification{ 
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 

    [self doRotationStuff:orientation: previousOrientation]; 
previousOrientation = orientation; 

} 

này hoạt động càng lâu càng, khi chương trình được khởi động, hướng thiết bị là chân dung, nhưng không nếu định hướng ban đầu là cảnh quan hoặc lộn ngược, bởi vì [tự doRotationStuff] làm thay đổi tương đối với sự khác biệt so với định hướng trước đó.

Có cách nào để phát hiện hướng hoặc khi khởi chạy hoặc ngay trước khi thiết bị được xoay?

Trả lời

3

Cập nhật:

Vì vậy, từ các cuộc thảo luận bình luận, dường như bạn không thể dựa vào [UIDevice currentDevice].orientation cho đến khi định hướng thực sự thay đổi cho lần đầu tiên. Nếu vậy, bạn có thể có thể hack nó bằng cách đọc số liệu gia tốc thô.

#define kUpdateFrequency 30 // Hz 
#define kUpdateCount 15 // So we init after half a second 
#define kFilteringFactor (1.0f/kUpdateCount) 

- (void)applicationDidFinishLaunching:(UIApplication *)app 
{ 
    [UIAccelerometer sharedAccelerometer].updateInterval = (1.0/kUpdateFrequency); 
    [UIAccelerometer sharedAccelerometer].delegate = self; 
    accelerometerCounter = 0; 
    ... 
} 

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)accel 
{ 
    // Average out the first kUpdateCount readings 
    // acceleration_[xyz] are ivars typed float 
    acceleration_x = (float)accel.x * kFilteringFactor + acceleration_x * (1.0f - kFilteringFactor); 
    acceleration_y = (float)accel.y * kFilteringFactor + acceleration_y * (1.0f - kFilteringFactor); 
    acceleration_z = (float)accel.z * kFilteringFactor + acceleration_z * (1.0f - kFilteringFactor); 

    accelerometerCounter++; 
    if (accelerometerCounter == kUpdateCount) 
    { 
     [self initOrientation]; 
     [UIAccelerometer sharedAccelerometer].delegate = nil; 
    } 
} 

- (void)initOrientation 
{ 
    // Figure out orientation from acceleration_[xyz] and set up your UI... 
} 

phản ứng gốc:

Liệu [UIDevice currentDevice].orientation trả lại đúng hướng trong applicationDidFinishLaunching:? Nếu có, bạn có thể thiết lập giao diện người dùng ban đầu của mình theo hướng đó.

Nếu thuộc tính đó không được đặt cho đến một thời gian sau đó, bạn có thể thử thử với performSelector:afterDelay: để khởi tạo giao diện người dùng sau một thời gian trễ nhỏ.

mẫu mã này là từ Kendall của câu trả lời dưới đây, thêm vào đây cho đầy đủ:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f]; 

Tôi không chắc chắn nếu một sự chậm trễ zero-thứ hai là đủ - điều này có nghĩa là mã cho getOriented sẽ chạy trong suốt đầu tiên đi qua vòng lặp chạy sự kiện. Bạn có thể cần phải đợi lâu hơn để đọc chỉ số gia tốc để đăng ký trên .

+0

Trong applicationDidFinishLaunching, [UIDevice currentDevice] .orientation là UIDeviceOrientationUnknown –

+0

Tôi không biết gì về thế nào tôi sẽ sử dụng performSelector: afterDelay. Bạn có thể đưa ra một ví dụ mã? –

+0

Tôi đã thử những gì bạn nói nhưng thậm chí [self performSelector: @selector (getOriented) withObject: nil afterDelay: 10.0f]; không có bất kỳ hiệu ứng nào –

-1

Đáp lại bình luận của bạn, tôi nghĩ tôi có thể đặt tốt hơn mã ở đây hơn trong một chú thích (mặc dù thực sự Daniel xứng đáng tín dụng ở đây):

trong applicationDidFinishLaunching:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f]; 

Sau đó, bạn chỉ cần phương thức gọi:

- (void) getOriented 
{ 
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 
    // save orientation somewhere 
} 
+0

Tôi đã thử những gì bạn nói nhưng thậm chí [self performSelector: @selector (getOriented) withObject: nil afterDelay: 10.0f]; Không có bất kỳ ảnh hưởng nào –

+0

Định hướng khi nó được gọi là mười giây sau đó là gì? Có vẻ như sau mười giây định hướng nên được đặt ... hoặc tại thời điểm đó, chỉ cần hỏi bộ điều khiển xem chính định hướng của nó là gì. –

+0

nó đã được UIDeviceOrientationUnknown –

1

Nữa, những câu trả lời này có vẻ hơi đỏ; Tôi không thể hiểu tại sao bạn không thể sử dụng sau đây được xây dựng trong phương pháp cho một lớp UIViewController:

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {} 

Phương pháp này được gọi tự động sau khi vòng xoay đã xảy ra (chứ không phải với shouldAutorotateToInterfaceOrientation mà chỉ cho bạn biết đó là khoảng xảy ra). Một cách thủ công, biến 'fromInterfaceOrientation' có chứa định hướng trước đó. Như tài liệu cũng nói, bạn có thể giả định rằng thuộc tính interfaceOrientation của khung nhìn đã được đặt theo hướng mới, vì vậy bạn có một phương thức có quyền truy cập vào hướng cũ và mới!

Nếu tôi đã bỏ lỡ điều gì đó và bạn đã bỏ qua việc có thể sử dụng phương pháp này, xin lỗi của tôi! Nó chỉ có vẻ kỳ lạ mà bạn đang tạo và lưu trữ một biến cho "định hướng trước đó" khi nó được cung cấp miễn phí trong phương pháp trên.

Hy vọng điều đó sẽ hữu ích!

+0

Điều đó sẽ làm việc nếu tôi đã có kế hoạch xoay giao diện, mà tôi không muốn làm. –

0

Một ví dụ hoàn chỉnh hơn về cách lấy hướng thiết bị từ đọc gia tốc có thể được tìm thấy here Là giải pháp dựa vào bài đọc tăng tốc, nó sẽ không hoạt động trên trình giả lập, vì vậy bạn sẽ phải làm việc trên thiết bị. .. vẫn đang tìm kiếm một giải pháp hoạt động trên trình mô phỏng.

12

Tùy thuộc vào hoàn cảnh của bạn, tùy chọn đơn giản hơn có thể là thuộc tính interfaceOrientation của lớp UIViewController. Điều này đúng trước khi quay.

+2

Cảm ơn! tôi không biết lĩnh vực htat tồn tại - tôi đã sử dụng định hướng của UIDevice, điều này không hữu ích lắm. – Chris

+0

Đây là lý do tại sao *** S.O Rocks! *** ... đã đi Nugging Futz cố gắng giải quyết một * * ho * * vấn đề định hướng đơn giản ... không có đầu mối ... tìm kiếm lần lượt lên câu trả lời của delany. –

1

Sử dụng tính năng này cho định hướng của giao diện người dùng nếu bạn cần xác định cách bạn đang trỏ.

Không phải 100% chắc chắn điều này là đúng, nhưng đi ra khỏi đỉnh đầu của tôi:

[[[UIApplication sharedApplication] statusBar] orientation] 
1

Dưới đây là một cách để có được định hướng khi ứng dụng tải đầu tiên và UIDeviceOrientation được thiết lập để UIDeviceOrientationUnknown. Bạn có thể xem thuộc tính biến đổi của khung nhìn xoay.

if(toInterface == UIDeviceOrientationUnknown) { 
    CGAffineTransform trans = navigationController.view.transform; 
    if(trans.b == 1 && trans.c == -1) 
     toInterface = UIDeviceOrientationLandscapeLeft; 
    else if(trans.b == -1 && trans.c == 1) 
     toInterface = UIDeviceOrientationLandscapeRight; 
    else if(trans.a == -1 && trans.d == -1) 
     toInterface = UIDeviceOrientationPortraitUpsideDown; 
    else 
     toInterface = UIDeviceOrientationPortrait; 
} 
+0

Đây là vàng! Nó sẽ cho bạn định hướng của một khung nhìn. Tôi đã sử dụng tính năng này với 'UIDeviceOrientationDidChangeNotification' để phát hiện định hướng trước đó của tôi. – cnotethegr8

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