Ios disable tap status bar to scroll top năm 2024

A lesser known user-interface feature on the iPhone is that touches in the status bar will usually scroll the main UIScrollView to the top, providing a quick way to scroll to the top of long documents.

This will work in your application when exactly one UIScrollView returns YES for the scrollsToTop property [YES is the default]. If more than one UIScrollView returns YES for this property [or the UIScrollView's

  • [void]sendEvent:[UIEvent ]anEvent { # define GS_EVENT_TYPE_OFFSET 2 # define GS_EVENT_X_OFFSET 6 # define GS_EVENT_Y_OFFSET 7 # define STATUS_BAR_TOUCH_DOWN 1015 // Traverse from the UIEvent to the GSEvent to the type int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]]; int eventType = eventMemory[GS_EVENT_TYPE_OFFSET]; // Look for status bar touches by event type if [eventType == STATUS_BAR_TOUCH_DOWN] { // The next 6 lines aren't essential but if you want to know where the // touch coordinates live, here they are: int xMemory = eventMemory[GS_EVENT_X_OFFSET]; int yMemory = eventMemory[GS_EVENT_Y_OFFSET]; typedef union {int intValue; float floatValue;} Int2Float; float x = [[Int2Float]xMemory].floatValue; float y = [[Int2Float]yMemory].floatValue; NSLog[@"Status bar down at %f, %f", x, y]; // Send a message to the delegate to handle the action [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer]; } else { [super sendEvent:anEvent]; } } `
1 returns

  • [void]sendEvent:[UIEvent ]anEvent

    {

    
    
    # define GS_EVENT_TYPE_OFFSET 2
    
    
    # define GS_EVENT_X_OFFSET 6
    
    
    # define GS_EVENT_Y_OFFSET 7
    
    
    # define STATUS_BAR_TOUCH_DOWN 1015
    
    // Traverse from the UIEvent to the GSEvent to the type
    int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
    // Look for status bar touches by event type
    if [eventType == STATUS_BAR_TOUCH_DOWN]
    {
        // The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are: 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];
        typedef union {int intValue; float floatValue;} Int2Float;
        float x = [[Int2Float]xMemory].floatValue;
        float y = [[Int2Float]yMemory].floatValue;
        NSLog[@"Status bar down at %f, %f", x, y];
        // Send a message to the delegate to handle the action
        [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
    
    }

    `

2 from

  • [void]sendEvent:[UIEvent ]anEvent { # define GS_EVENT_TYPE_OFFSET 2 # define GS_EVENT_X_OFFSET 6 # define GS_EVENT_Y_OFFSET 7 # define STATUS_BAR_TOUCH_DOWN 1015 // Traverse from the UIEvent to the GSEvent to the type int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]]; int eventType = eventMemory[GS_EVENT_TYPE_OFFSET]; // Look for status bar touches by event type if [eventType == STATUS_BAR_TOUCH_DOWN] { // The next 6 lines aren't essential but if you want to know where the // touch coordinates live, here they are: int xMemory = eventMemory[GS_EVENT_X_OFFSET]; int yMemory = eventMemory[GS_EVENT_Y_OFFSET]; typedef union {int intValue; float floatValue;} Int2Float; float x = [[Int2Float]xMemory].floatValue; float y = [[Int2Float]yMemory].floatValue; NSLog[@"Status bar down at %f, %f", x, y]; // Send a message to the delegate to handle the action [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer]; } else { [super sendEvent:anEvent]; } } `
  1. the scroll to top functionality will be disabled.
That's the ordinary functionality but how do we achieve different functionality? ## The HiddenDrawer sample appliction ![][//www.cocoawithlove.com/assets/objc-era/hidden_drawer_screenshots.png] These screenshots show the HiddenDrawer sample application. When the status bar is tapped on the left, the hidden drawer animates out from under the status bar, resulting in the state shown on the right. ## Stealing status bar touch events The trickiest part of the sample application is detecting a touch in the status bar. By implementing a custom

  • [void]sendEvent:[UIEvent ]anEvent

    {

    
    
    # define GS_EVENT_TYPE_OFFSET 2
    
    
    # define GS_EVENT_X_OFFSET 6
    
    
    # define GS_EVENT_Y_OFFSET 7
    
    
    # define STATUS_BAR_TOUCH_DOWN 1015
    
    // Traverse from the UIEvent to the GSEvent to the type
    int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
    // Look for status bar touches by event type
    if [eventType == STATUS_BAR_TOUCH_DOWN]
    {
        // The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are: 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];
        typedef union {int intValue; float floatValue;} Int2Float;
        float x = [[Int2Float]xMemory].floatValue;
        float y = [[Int2Float]yMemory].floatValue;
        NSLog[@"Status bar down at %f, %f", x, y];
        // Send a message to the delegate to handle the action
        [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
    
    }

    `

4 method on a

  • [void]sendEvent:[UIEvent ]anEvent { # define GS_EVENT_TYPE_OFFSET 2 # define GS_EVENT_X_OFFSET 6 # define GS_EVENT_Y_OFFSET 7 # define STATUS_BAR_TOUCH_DOWN 1015 // Traverse from the UIEvent to the GSEvent to the type int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]]; int eventType = eventMemory[GS_EVENT_TYPE_OFFSET]; // Look for status bar touches by event type if [eventType == STATUS_BAR_TOUCH_DOWN] { // The next 6 lines aren't essential but if you want to know where the // touch coordinates live, here they are: int xMemory = eventMemory[GS_EVENT_X_OFFSET]; int yMemory = eventMemory[GS_EVENT_Y_OFFSET]; typedef union {int intValue; float floatValue;} Int2Float; float x = [[Int2Float]xMemory].floatValue; float y = [[Int2Float]yMemory].floatValue; NSLog[@"Status bar down at %f, %f", x, y]; // Send a message to the delegate to handle the action [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer]; } else { [super sendEvent:anEvent]; } } `
5 and setting a breakpoint in that method, you can see in the debugger stack that the

  • [void]sendEvent:[UIEvent ]anEvent

    {

    
    
    # define GS_EVENT_TYPE_OFFSET 2
    
    
    # define GS_EVENT_X_OFFSET 6
    
    
    # define GS_EVENT_Y_OFFSET 7
    
    
    # define STATUS_BAR_TOUCH_DOWN 1015
    
    // Traverse from the UIEvent to the GSEvent to the type
    int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
    // Look for status bar touches by event type
    if [eventType == STATUS_BAR_TOUCH_DOWN]
    {
        // The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are: 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];
        typedef union {int intValue; float floatValue;} Int2Float;
        float x = [[Int2Float]xMemory].floatValue;
        float y = [[Int2Float]yMemory].floatValue;
        NSLog[@"Status bar down at %f, %f", x, y];
        // Send a message to the delegate to handle the action
        [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
    
    }

    `

6

  • [void]sendEvent:[UIEvent ]anEvent { # define GS_EVENT_TYPE_OFFSET 2 # define GS_EVENT_X_OFFSET 6 # define GS_EVENT_Y_OFFSET 7 # define STATUS_BAR_TOUCH_DOWN 1015 // Traverse from the UIEvent to the GSEvent to the type int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]]; int eventType = eventMemory[GS_EVENT_TYPE_OFFSET]; // Look for status bar touches by event type if [eventType == STATUS_BAR_TOUCH_DOWN] { // The next 6 lines aren't essential but if you want to know where the // touch coordinates live, here they are: int xMemory = eventMemory[GS_EVENT_X_OFFSET]; int yMemory = eventMemory[GS_EVENT_Y_OFFSET]; typedef union {int intValue; float floatValue;} Int2Float; float x = [[Int2Float]xMemory].floatValue; float y = [[Int2Float]yMemory].floatValue; NSLog[@"Status bar down at %f, %f", x, y]; // Send a message to the delegate to handle the action [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer]; } else { [super sendEvent:anEvent]; } } `
7 method is invoked for status bar touches, so that's where we'll begin. ### CustomApplication Overriding

  • [void]sendEvent:[UIEvent ]anEvent

    {

    
    
    # define GS_EVENT_TYPE_OFFSET 2
    
    
    # define GS_EVENT_X_OFFSET 6
    
    
    # define GS_EVENT_Y_OFFSET 7
    
    
    # define STATUS_BAR_TOUCH_DOWN 1015
    
    // Traverse from the UIEvent to the GSEvent to the type
    int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
    // Look for status bar touches by event type
    if [eventType == STATUS_BAR_TOUCH_DOWN]
    {
        // The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are: 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];
        typedef union {int intValue; float floatValue;} Int2Float;
        float x = [[Int2Float]xMemory].floatValue;
        float y = [[Int2Float]yMemory].floatValue;
        NSLog[@"Status bar down at %f, %f", x, y];
        // Send a message to the delegate to handle the action
        [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
    
    }

    `

6 is extremely rare so I'll explain how to make it work. Once you create the subclass of

  • [void]sendEvent:[UIEvent ]anEvent { # define GS_EVENT_TYPE_OFFSET 2 # define GS_EVENT_X_OFFSET 6 # define GS_EVENT_Y_OFFSET 7 # define STATUS_BAR_TOUCH_DOWN 1015 // Traverse from the UIEvent to the GSEvent to the type int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]]; int eventType = eventMemory[GS_EVENT_TYPE_OFFSET]; // Look for status bar touches by event type if [eventType == STATUS_BAR_TOUCH_DOWN] { // The next 6 lines aren't essential but if you want to know where the // touch coordinates live, here they are: int xMemory = eventMemory[GS_EVENT_X_OFFSET]; int yMemory = eventMemory[GS_EVENT_Y_OFFSET]; typedef union {int intValue; float floatValue;} Int2Float; float x = [[Int2Float]xMemory].floatValue; float y = [[Int2Float]yMemory].floatValue; NSLog[@"Status bar down at %f, %f", x, y]; // Send a message to the delegate to handle the action [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer]; } else { [super sendEvent:anEvent]; } } `
6 you need to tell the program to use that subclass. In Cocoa Senior [Mac OS X] you specify application subclasses in the Info.plist file. In Cocoa Touch, you specify custom application subclasses by name in the
drawerController = [[HiddenDrawerViewController alloc] init]; // Position the drawer below the status bar CGRect drawerFrame = drawerController.view.frame; CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; drawerFrame.origin.x = statusBarFrame.origin.x; drawerFrame.size.width = statusBarFrame.size.width; drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height; // For the animation, move the drawer up by its own height. drawerFrame.origin.y -= drawerFrame.size.height; // Place the drawer and add it to the window drawerController.view.frame = drawerFrame; [window addSubview:drawerController.view]; // Start the animation [UIView beginAnimations:nil context:nil]; // Move the table down CGRect tableFrame = viewController.view.frame; tableFrame.origin.y += drawerFrame.size.height; viewController.view.frame = tableFrame; // Move the drawer down drawerFrame.origin.y += drawerFrame.size.height; drawerController.view.frame = drawerFrame; // Commit the animation [UIView commitAnimations];

0 function in the 
drawerController = [[HiddenDrawerViewController alloc] init]; // Position the drawer below the status bar CGRect drawerFrame = drawerController.view.frame; CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; drawerFrame.origin.x = statusBarFrame.origin.x; drawerFrame.size.width = statusBarFrame.size.width; drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height; // For the animation, move the drawer up by its own height. drawerFrame.origin.y -= drawerFrame.size.height; // Place the drawer and add it to the window drawerController.view.frame = drawerFrame; [window addSubview:drawerController.view]; // Start the animation [UIView beginAnimations:nil context:nil]; // Move the table down CGRect tableFrame = viewController.view.frame; tableFrame.origin.y += drawerFrame.size.height; viewController.view.frame = tableFrame; // Move the drawer down drawerFrame.origin.y += drawerFrame.size.height; drawerController.view.frame = drawerFrame; // Commit the animation [UIView commitAnimations];

1 file:
int retVal = UIApplicationMain[argc, argv, @"CustomApplication", nil];

### sendEvent:

The only method override we need in 
drawerController = [[HiddenDrawerViewController alloc] init]; // Position the drawer below the status bar CGRect drawerFrame = drawerController.view.frame; CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; drawerFrame.origin.x = statusBarFrame.origin.x; drawerFrame.size.width = statusBarFrame.size.width; drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height; // For the animation, move the drawer up by its own height. drawerFrame.origin.y -= drawerFrame.size.height; // Place the drawer and add it to the window drawerController.view.frame = drawerFrame; [window addSubview:drawerController.view]; // Start the animation [UIView beginAnimations:nil context:nil]; // Move the table down CGRect tableFrame = viewController.view.frame; tableFrame.origin.y += drawerFrame.size.height; viewController.view.frame = tableFrame; // Move the drawer down drawerFrame.origin.y += drawerFrame.size.height; drawerController.view.frame = drawerFrame; // Commit the animation [UIView commitAnimations];

2 is 

  • [void]sendEvent:[UIEvent ]anEvent

    {

    
    
    # define GS_EVENT_TYPE_OFFSET 2
    
    
    # define GS_EVENT_X_OFFSET 6
    
    
    # define GS_EVENT_Y_OFFSET 7
    
    
    # define STATUS_BAR_TOUCH_DOWN 1015
    
    // Traverse from the UIEvent to the GSEvent to the type
    int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
    // Look for status bar touches by event type
    if [eventType == STATUS_BAR_TOUCH_DOWN]
    {
        // The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are: 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];
        typedef union {int intValue; float floatValue;} Int2Float;
        float x = [[Int2Float]xMemory].floatValue;
        float y = [[Int2Float]yMemory].floatValue;
        NSLog[@"Status bar down at %f, %f", x, y];
        // Send a message to the delegate to handle the action
        [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
    
    }

    `

7. The difficult part is then working out from the

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

4 which events are status bar touch events — unfortunately, the

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

5 method returns an empty array for status bar touches.

Instead, we delve into the secret

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

6.

I previously accessed

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

6 in my post Synthesizing a touch event on the iPhone. In that post, I created a

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

8 class and a fake

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

9 class to access the required fields. This time, I'm going to use a different approach and jump straight to the data I need.

  • [void]sendEvent:[UIEvent ]anEvent { # define GS_EVENT_TYPE_OFFSET 2 # define GS_EVENT_X_OFFSET 6 # define GS_EVENT_Y_OFFSET 7 # define STATUS_BAR_TOUCH_DOWN 1015 // Traverse from the UIEvent to the GSEvent to the type int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]]; int eventType = eventMemory[GS_EVENT_TYPE_OFFSET]; // Look for status bar touches by event type if [eventType == STATUS_BAR_TOUCH_DOWN] { // The next 6 lines aren't essential but if you want to know where the // touch coordinates live, here they are: int xMemory = eventMemory[GS_EVENT_X_OFFSET]; int yMemory = eventMemory[GS_EVENT_Y_OFFSET]; typedef union {int intValue; float floatValue;} Int2Float; float x = [[Int2Float]xMemory].floatValue; float y = [[Int2Float]yMemory].floatValue; NSLog[@"Status bar down at %f, %f", x, y]; // Send a message to the delegate to handle the action [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer]; } else { [super sendEvent:anEvent]; } } `
You may be curious to know where the `UIScrollView`0 values come from. The answer is that I spent a while staring at the raw memory values in the
drawerController = [[HiddenDrawerViewController alloc] init]; // Position the drawer below the status bar CGRect drawerFrame = drawerController.view.frame; CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; drawerFrame.origin.x = statusBarFrame.origin.x; drawerFrame.size.width = statusBarFrame.size.width; drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height; // For the animation, move the drawer up by its own height. drawerFrame.origin.y -= drawerFrame.size.height; // Place the drawer and add it to the window drawerController.view.frame = drawerFrame; [window addSubview:drawerController.view]; // Start the animation [UIView beginAnimations:nil context:nil]; // Move the table down CGRect tableFrame = viewController.view.frame; tableFrame.origin.y += drawerFrame.size.height; viewController.view.frame = tableFrame; // Move the drawer down drawerFrame.origin.y += drawerFrame.size.height; drawerController.view.frame = drawerFrame; // Commit the animation [UIView commitAnimations];

6 object while deliberately causing status bar and other touch events — nothing fancier than that. It's tricky and unreliable. If it works at all in iPhoneSDK3.0, it'll be pure luck.

I also use a `UIScrollView`2 here. This is because I step through memory as `UIScrollView`3s and in C, a basic cast from `UIScrollView`3 to `UIScrollView`5 causes a value conversion [I want a reinterpret, not a value conversion].

I also chose to suppress status bar touch events going through to the 

  • [void]sendEvent:[UIEvent ]anEvent

    {

    
    
    # define GS_EVENT_TYPE_OFFSET 2
    
    
    # define GS_EVENT_X_OFFSET 6
    
    
    # define GS_EVENT_Y_OFFSET 7
    
    
    # define STATUS_BAR_TOUCH_DOWN 1015
    
    // Traverse from the UIEvent to the GSEvent to the type
    int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
    // Look for status bar touches by event type
    if [eventType == STATUS_BAR_TOUCH_DOWN]
    {
        // The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are: 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];
        typedef union {int intValue; float floatValue;} Int2Float;
        float x = [[Int2Float]xMemory].floatValue;
        float y = [[Int2Float]yMemory].floatValue;
        NSLog[@"Status bar down at %f, %f", x, y];
        // Send a message to the delegate to handle the action
        [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
    
    }

    `

5 by the normal route. If you want to re-enable this behavior, you can take the `UIScrollView`7 line out of the `UIScrollView`8 block and put it in the main method body.

Animating the drawer

The

  • [void]sendEvent:[UIEvent ]anEvent { # define GS_EVENT_TYPE_OFFSET 2 # define GS_EVENT_X_OFFSET 6 # define GS_EVENT_Y_OFFSET 7 # define STATUS_BAR_TOUCH_DOWN 1015 // Traverse from the UIEvent to the GSEvent to the type int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]]; int eventType = eventMemory[GS_EVENT_TYPE_OFFSET]; // Look for status bar touches by event type if [eventType == STATUS_BAR_TOUCH_DOWN] { // The next 6 lines aren't essential but if you want to know where the // touch coordinates live, here they are: int xMemory = eventMemory[GS_EVENT_X_OFFSET]; int yMemory = eventMemory[GS_EVENT_Y_OFFSET]; typedef union {int intValue; float floatValue;} Int2Float; float x = [[Int2Float]xMemory].floatValue; float y = [[Int2Float]yMemory].floatValue; NSLog[@"Status bar down at %f, %f", x, y]; // Send a message to the delegate to handle the action [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer]; } else { [super sendEvent:anEvent]; } } `
7 implementation above invokes the `UIScrollView`0 method on the application's

  • [void]sendEvent:[UIEvent ]anEvent

    {

    
    
    # define GS_EVENT_TYPE_OFFSET 2
    
    
    # define GS_EVENT_X_OFFSET 6
    
    
    # define GS_EVENT_Y_OFFSET 7
    
    
    # define STATUS_BAR_TOUCH_DOWN 1015
    
    // Traverse from the UIEvent to the GSEvent to the type
    int *eventMemory = [int ][anEvent performSelector:@selector[_gsEvent]];
    int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
    // Look for status bar touches by event type
    if [eventType == STATUS_BAR_TOUCH_DOWN]
    {
        // The next 6 lines aren't essential but if you want to know where the
       // touch coordinates live, here they are: 
        int xMemory = eventMemory[GS_EVENT_X_OFFSET];
        int yMemory = eventMemory[GS_EVENT_Y_OFFSET];
        typedef union {int intValue; float floatValue;} Int2Float;
        float x = [[Int2Float]xMemory].floatValue;
        float y = [[Int2Float]yMemory].floatValue;
        NSLog[@"Status bar down at %f, %f", x, y];
        // Send a message to the delegate to handle the action
        [[HiddenDrawerAppDelegate *]self.delegate toggleDrawer];
    }
    else
    {
        [super sendEvent:anEvent];
    }
    
    }

    `

1.

All that's required is to animate the drawer's view in and push the table's view down:

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

If you download the whole project, you'll see that there's also an animate up and remove branch that gets run if the `UIScrollView`2 already exists.

Conclusion

You can download the HiddenDrawer sample project [30kB] to see the whole application in action.

A hidden drawer under the status bar isn't necessarily something that every iPhone application should have but the obscure, secretive nature of it appeals to me.

The approach of determining which

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

4 we want by the `UIScrollView`4 field in the

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

6 is a little precarious. Apple are free to change the structure of

drawerController = [[HiddenDrawerViewController alloc] init];
// Position the drawer below the status bar
CGRect drawerFrame = drawerController.view.frame;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
drawerFrame.origin.x = statusBarFrame.origin.x;
drawerFrame.size.width = statusBarFrame.size.width;
drawerFrame.origin.y = statusBarFrame.origin.y + statusBarFrame.size.height;
// For the animation, move the drawer up by its own height.
drawerFrame.origin.y -= drawerFrame.size.height;
// Place the drawer and add it to the window
drawerController.view.frame = drawerFrame;
[window addSubview:drawerController.view];
// Start the animation
[UIView beginAnimations:nil context:nil];
// Move the table down
CGRect tableFrame = viewController.view.frame;
tableFrame.origin.y += drawerFrame.size.height;
viewController.view.frame = tableFrame;
// Move the drawer down
drawerFrame.origin.y += drawerFrame.size.height;
drawerController.view.frame = drawerFrame;
// Commit the animation
[UIView commitAnimations];

6 at any time, which could cause your application to misbehave or crash so this type of code would need to be tested on each iPhone OS release to ensure that it still works.

How do I stop my iPhone from scrolling to the top?

To solve iPhone scrolls on its own, try adjusting the 3D or haptic touch sensitivity as follows:.

Launch the Settings app from your device..

Next, scroll down to choose Accessibility..

Under the Physical and Motor, hit Touch option..

Choose 3D & Haptic Touch..

Here, toggle on the 3D Touch..

How do I turn off scroll top?

Set overflow-x to Hidden to Disable Horizontal Scroll Bar in CSS. For disabling the horizontal scrolling we can set the property overflow-x to hidden along with the height is set to 100%. Everything else remains the same. Let's see the implementation for this.

How do I turn off scroll feature?

overflow. property. Here are two possible ways to achieve this: ... .

overflow. property to..

hidden. . This will hide any content that overflows the body and prevent scrolling. ... .

position. property to..

fixed. and the..

width. and..

height. properties to..

100% . This will fix the body element in place, effectively disabling scrolling..

Chủ Đề