Ancient Programming

What I encounter in my software part of life is in danger of being commented upon here

Archive for the 'mac' Category


Animating the drag drop example

Posted by Jacob von Eyben on 9th April 2012

As an update to my original ios drag drop post I have added an animation to the snap back to original position.

The changes is made to the DragContext.m file where the snapToOrignalPostion is changed to look like the following:

- (void)snapToOriginalPosition {
    [UIView animateWithDuration:0.3 animations:^() {
        CGPoint originalPointInSuperView = [_draggedView.superview convertPoint:_originalPosition fromView:_originalView];
        _draggedView.frame = CGRectMake(originalPointInSuperView.x, originalPointInSuperView.y, _draggedView.frame.size.width, _draggedView.frame.size.height);
    } completion:^(BOOL finished) {
        _draggedView.frame = CGRectMake(_originalPosition.x, _originalPosition.y, _draggedView.frame.size.width, _draggedView.frame.size.height);
        [_draggedView removeFromSuperview];
        [_originalView addSubview:_draggedView];
    }];
}

First we animate the dragged object back to the original position (in the super view containing all drag objects and drop areas). When the animation is completed, we change the superview.

Posted in animation, how to, ios, ipad, iphone, mac, objective-c | 1 Comment »

How to implement drop shadow and immerse effects for UIViews

Posted by Jacob von Eyben on 30th December 2011


It is pretty easy to create a drop shadow or immerse effect like this in iOS.

Here is two static helper methods I created to do the trick.
The first method is capable of dropping a shadow from one view onto another:

+ (void)dropColor:(UIColor *)dropColor from:(UIView *)dropFromView onto:(UIView *)toView x:(CGFloat)x y:(CGFloat)y {
    CGFloat cornerRadius = [[dropFromView layer] cornerRadius];
    UIView *shadow = [[[UIView alloc] initWithFrame:dropFromView.frame] autorelease];
    [[shadow layer] setCornerRadius:cornerRadius];
    CGRect dropRect = dropFromView.frame;
    shadow.frame = CGRectMake(dropRect.origin.x + x, dropRect.origin.y + y, dropRect.size.width, dropRect.size.height);
    [shadow setBackgroundColor:dropColor];
    [toView insertSubview:shadow belowSubview:dropFromView];
}

The second takes advantage of the first and creates an effect that makes it looks like the first view is immersed into the other:

+ (void)immerse:(UIView *)immerseView into:(UIView *)toView depth:(CGFloat)depth {
    CGFloat x = 0.7;
    CGFloat y = 1.4;
    [UIUtil dropColor:[UIColor darkGrayColor] from:immerseView onto:toView x:-1 * x * depth y:-1 * y * depth];
    [UIUtil dropColor:[UIColor whiteColor] from:immerseView onto:toView x:x*depth y:y*depth];
}

The following effect can be added to a tableview by doing this:

- (void)viewDidLoad {
    [super viewDidLoad];
    [[_tableView layer] setCornerRadius:5];
    [UIUtil immerse:_tableView into:self.view depth:1.5];
}

Posted in ios, iphone, mac, objective-c | No Comments »

Extend UITabBarController with an arrow marker

Posted by Jacob von Eyben on 18th September 2011

I have seen a couple of iPhone apps using an UITabBarController having an arrow showing just above the selected UITabBarItem as an extra visual pointer to the current visible view. At the same time the arrow moves animated between the items as the user selects them.

I decided to try implement the same effect and I have shared my solution here.

The solution is made generic enough to handle any number of UITabBarItems in the UITabBarController and basically what it does is:

  • In the viewDidAppear selector, the arrow is places above the first element. This is done by calculating the size and location (also known as the CGRect) of the first UITabBarItem. Then a new UIImageView is created and positioned centered and above the UITabBarItem. Again some math is used to find the offset to use for the newly created UIImageView
  • In the didSelectItem a transition is used to animate the movement of the arrow between the items as they are selected.

My CustomUITabBarController.h and CustomUITabBarController.m files looks like this:

@interface CustomUITabBarController : UITabBarController {
@private
    UIImageView *_imageView;
}
@end

The actual implementation looks like follows:

@interface CustomUITabBarController ()
@property(nonatomic, retain) UIImageView *imageView;
@end

@implementation CustomUITabBarController

@synthesize imageView = _imageView;

- (CGRect) rectForItem:(UITabBarItem *)item {
    NSUInteger itemsInTabBar = [self.tabBar.items count];

    CGSize itemSize = CGSizeMake(self.tabBar.frame.size.width / itemsInTabBar, self.tabBar.frame.size.height);
    //find current selected item index
    int currentIndexSelected = 0;
    //if the item is nil, we keep the index at zero (selects the first element)
    if (item != nil) {
        for (int i = 0; i < itemsInTabBar; i++) {
            UITabBarItem *currentItem = [self.tabBar.items objectAtIndex:(NSUInteger) i];
            if (currentItem == item) {
                currentIndexSelected = i;
            }
        }
    }
    //construct the rect that defines the current selected item
    return CGRectMake(lrint(currentIndexSelected * itemSize.width), itemSize.height, itemSize.width, itemSize.height);
}

- (CGRect)getRectForImage:(UIImage *)markerImage andTabPosition:(CGRect)itemRect {
    CGFloat windowHeight = [UIScreen mainScreen].bounds.size.height;
    CGRect markerImageRect = CGRectMake(itemRect.origin.x + lrint(itemRect.size.width / 2) - lrint(markerImage.size.width / 2), windowHeight - itemRect.size.height - markerImage.size.height, markerImage.size.width, markerImage.size.height);
    return markerImageRect;
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];  //To change the template use AppCode | Preferences | File Templates.
    UIImage * markerImage = [UIImage imageNamed:@"tabMarker.png"];
    CGRect firstItemRect = [self rectForItem:nil];
    CGRect markerImageRect = [self getRectForImage:markerImage andTabPosition:firstItemRect];
    _imageView = [[UIImageView alloc] initWithFrame:markerImageRect];
    _imageView.image = markerImage;
    [self.view addSubview:_imageView];
}

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
    CGRect selectedItemRect = [self rectForItem:item];

    [UIView beginAnimations:@"move tabMarker" context:nil];
    [UIView setAnimationDuration:0.3f];
    _imageView.transform = CGAffineTransformMakeTranslation(selectedItemRect.origin.x,0);
    [UIView commitAnimations];
}
...
@end

Posted in how to, ios, iphone, mac, objective-c | No Comments »

Automatically reconnect to NAS under Mac OS X

Posted by Jacob von Eyben on 27th June 2008

Mac OS X doesn’t remount network drives when booted. You have to do this yourselves.

You can easily automate this by creating an application using the automator and add it to your login items.

Automator - create application

You automator script should contain two items:

  • Get Specified Servers
  • Connect to Servers

Save the script as an application and put it into login items for your user account. This will execute your small application each time you login and you should be reconnected to your NAS on startup.

Posted in how to, mac | No Comments »