如何制作iPhone文件夹之类的东西?

发布于 2024-10-08 16:58:14 字数 773 浏览 5 评论 0原文

我想知道是否有办法可以将我的视图转换为看起来像 iPhone 文件夹。换句话说,我希望我的视图在中间的某个位置分开并显示其下方的视图。这可能吗?

alt text

编辑: 根据下面的建议,我可以通过执行以下操作来截取我的应用程序的屏幕截图:

UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

但是,不确定如何处理它。

编辑:2 我已经弄清楚如何向我的视图添加一些阴影,这就是我所实现的(裁剪以显示相关部分):

“替代文本”

编辑:3

http://github.com/jwilling/JWFolders

I'm wanting to know if there's a way I can transform my view to look something like iPhone folders. In other words, I want my view to split somewhere in the middle and reveal a view underneath it. Is this possible?

alt text

EDIT:
Per the suggestion below, I could take a screenshot of my application by doing this:

UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Not sure what to do with this, however.

EDIT:2
I've figured out how to add some shadows to my view, and here's what I've achieved (cropped to show relevant part):

alt text

EDIT:3

http://github.com/jwilling/JWFolders

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

随风而去 2024-10-15 16:58:14

基本的想法是拍一张你当前状态的照片并将其分割到某个地方。然后通过设置新框架来为两个部分设置动画。我不知道如何以编程方式截取屏幕截图,所以我无法提供示例代码...

编辑:嘿嘿,它看起来不太好,但它有效 ^^

// wouldn't be sharp on retina displays, instead use "withOptions" and set scale to 0.0
// UIGraphicsBeginImageContext(self.view.bounds.size);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *f = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGRect fstRect = CGRectMake(0, 0, 320, 200);
CGRect sndRect = CGRectMake(0, 200, 320, 260); // was 0,200,320,280


CGImageRef fImageRef = CGImageCreateWithImageInRect([f CGImage], fstRect);
UIImage *fCroppedImage = [UIImage imageWithCGImage:fImageRef];
CGImageRelease(fImageRef);

CGImageRef sImageRef = CGImageCreateWithImageInRect([f CGImage], sndRect);
UIImage *sCroppedImage = [UIImage imageWithCGImage:sImageRef];
CGImageRelease(sImageRef);


UIImageView *first = [[UIImageView alloc]initWithFrame:fstRect];
first.image = fCroppedImage;
//first.contentMode = UIViewContentModeTop;
UIImageView *second = [[UIImageView alloc]initWithFrame:sndRect];
second.image = sCroppedImage;
//second.contentMode = UIViewContentModeBottom;

UIView *blank = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
blank.backgroundColor = [UIColor darkGrayColor];

[self.view addSubview:blank];
[self.view addSubview:first];
[self.view addSubview:second];

[UIView animateWithDuration:2.0 animations:^{
    second.center = CGPointMake(second.center.x, second.center.y+75);
}];

您可以取消注释两行 .contentMode 和质量会提高,但在我的情况下,子视图的偏移量为 10px 左右(您可以通过为两个子视图设置背景颜色来看到它)

//编辑 2:好的发现了该错误。使用了整个 320x480 屏幕,但必须切断状态栏,因此它应该是 320x460 并且一切都工作得很好;)

the basic thought will be to take a picture of your current state and split it somewhere. Then animate both parts by setting a new frame. I don't know how to take a screenshot programmatically so I can't provide sample code…

EDIT: hey hey it's not looking great but it works ^^

// wouldn't be sharp on retina displays, instead use "withOptions" and set scale to 0.0
// UIGraphicsBeginImageContext(self.view.bounds.size);
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *f = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGRect fstRect = CGRectMake(0, 0, 320, 200);
CGRect sndRect = CGRectMake(0, 200, 320, 260); // was 0,200,320,280


CGImageRef fImageRef = CGImageCreateWithImageInRect([f CGImage], fstRect);
UIImage *fCroppedImage = [UIImage imageWithCGImage:fImageRef];
CGImageRelease(fImageRef);

CGImageRef sImageRef = CGImageCreateWithImageInRect([f CGImage], sndRect);
UIImage *sCroppedImage = [UIImage imageWithCGImage:sImageRef];
CGImageRelease(sImageRef);


UIImageView *first = [[UIImageView alloc]initWithFrame:fstRect];
first.image = fCroppedImage;
//first.contentMode = UIViewContentModeTop;
UIImageView *second = [[UIImageView alloc]initWithFrame:sndRect];
second.image = sCroppedImage;
//second.contentMode = UIViewContentModeBottom;

UIView *blank = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
blank.backgroundColor = [UIColor darkGrayColor];

[self.view addSubview:blank];
[self.view addSubview:first];
[self.view addSubview:second];

[UIView animateWithDuration:2.0 animations:^{
    second.center = CGPointMake(second.center.x, second.center.y+75);
}];

You can uncomment the two .contentMode lines and the quality will improve but in my case the subview has an offset of 10px or so (you can see it by setting a background color to both subviews)

//EDIT 2: ok found that bug. Had used the whole 320x480 screen, but had to cut off the status bar so it should be 320x460 and all is working great ;)

梦与时光遇 2024-10-15 16:58:14

您可以为每行图标使用单独的视图,而不是拍摄视图快照。您必须做更多的工作来重新定位内容,但是当文件夹打开时,行不会是静态的(换句话说,它们将根据需要不断重新绘制)。

Instead of taking a snapshot of the view, you could use a separate view for each row of icons. You'll have to do a bit more work with repositioning stuff, but the rows won't be static when the folder is open (in other words, they'll keep redrawing as necessary).

夏日浅笑〃 2024-10-15 16:58:14

我以 relikd 代码为基础,并使其更加动态。

您可以在调用该函数时指定分割位置和方向,我在分割图像中添加了边框。

#define splitAnimationTime 0.5
- (void)split:(SplitDirection)splitDirection
 atYPostition:(int)splitYPosition
withRevealedViewHeight:(int)revealedViewHeight{

    // wouldn't be sharp on retina displays, instead use "withOptions" and set scale to 0.0
    // UIGraphicsBeginImageContext(self.view.bounds.size);
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *f = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGRect fullScreenRect = [self getScreenFrameForCurrentOrientation];

    CGRect upperSplitRect = CGRectMake(0, 0,fullScreenRect.size.width, splitYPosition);
    CGRect lowerSplitRect = CGRectMake(0, splitYPosition, fullScreenRect.size.width, fullScreenRect.size.height-splitYPosition);


    CGImageRef upperImageRef = CGImageCreateWithImageInRect([f CGImage], upperSplitRect);
    UIImage *upperCroppedImage = [UIImage imageWithCGImage:upperImageRef];
    CGImageRelease(upperImageRef);

    CGImageRef lowerImageRef = CGImageCreateWithImageInRect([f CGImage], lowerSplitRect);
    UIImage *lowerCroppedImage = [UIImage imageWithCGImage:lowerImageRef];
    CGImageRelease(lowerImageRef);


    UIImageView *upperImage = [[UIImageView alloc]initWithFrame:upperSplitRect];
    upperImage.image = upperCroppedImage;
    //first.contentMode = UIViewContentModeTop;

    UIView *upperBoarder = [[UIView alloc]initWithFrame:CGRectMake(0, splitYPosition, fullScreenRect.size.width, 1)];
    upperBoarder.backgroundColor = [UIColor whiteColor];
    [upperImage addSubview:upperBoarder];


    UIImageView *lowerImage = [[UIImageView alloc]initWithFrame:lowerSplitRect];
    lowerImage.image = lowerCroppedImage;
    //second.contentMode = UIViewContentModeBottom;

    UIView *lowerBoarder = [[UIView alloc]initWithFrame:CGRectMake(0, 0, fullScreenRect.size.width, 1)];
    lowerBoarder.backgroundColor = [UIColor whiteColor];
    [lowerImage addSubview:lowerBoarder];

    int reveledViewYPosition = splitYPosition;

    if(splitDirection==SplitDirectionUp){
        reveledViewYPosition = splitYPosition - revealedViewHeight;
    }


    UIView *revealedView = [[UIView alloc]initWithFrame:CGRectMake(0, reveledViewYPosition, fullScreenRect.size.width, revealedViewHeight)];
    revealedView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];


    [self.view addSubview:revealedView];
    [self.view addSubview:upperImage];
    [self.view addSubview:lowerImage];

    [UIView animateWithDuration:splitAnimationTime animations:^{
        if(splitDirection==SplitDirectionUp){
            upperImage.center = CGPointMake(upperImage.center.x, upperImage.center.y-revealedViewHeight);
        } else { //assume down
            lowerImage.center = CGPointMake(lowerImage.center.x, lowerImage.center.y+revealedViewHeight);
        }
    }];
}

这意味着我可以这样调用它:

[self split:SplitDirectionUp atYPostition:500 withRevealedViewHeight:200];

我在更新的 split 函数中使用了这些便利函数:

- (CGRect)getScreenFrameForCurrentOrientation {
    return [self getScreenFrameForOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

- (CGRect)getScreenFrameForOrientation:(UIInterfaceOrientation)orientation {

    UIScreen *screen = [UIScreen mainScreen];
    CGRect fullScreenRect = screen.bounds;
    BOOL statusBarHidden = [UIApplication sharedApplication].statusBarHidden;

    //implicitly in Portrait orientation.
    if(orientation == UIInterfaceOrientationLandscapeRight || orientation ==  UIInterfaceOrientationLandscapeLeft){
        CGRect temp = CGRectZero;
        temp.size.width = fullScreenRect.size.height;
        temp.size.height = fullScreenRect.size.width;
        fullScreenRect = temp;
    }

    if(!statusBarHidden){
        CGFloat statusBarHeight = 20;
        fullScreenRect.size.height -= statusBarHeight;
    }

    return fullScreenRect;
}

并且这个枚举:

typedef enum SplitDirection
{
    SplitDirectionDown,
    SplitDirectionUp
}SplitDirection;

添加返回正常函数并添加箭头将是一个很好的补充。

I took relikd's code as a base and made it a bit more dynamic.

You can specify split position and direction when calling the function and I added a boarder to the split images.

#define splitAnimationTime 0.5
- (void)split:(SplitDirection)splitDirection
 atYPostition:(int)splitYPosition
withRevealedViewHeight:(int)revealedViewHeight{

    // wouldn't be sharp on retina displays, instead use "withOptions" and set scale to 0.0
    // UIGraphicsBeginImageContext(self.view.bounds.size);
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *f = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGRect fullScreenRect = [self getScreenFrameForCurrentOrientation];

    CGRect upperSplitRect = CGRectMake(0, 0,fullScreenRect.size.width, splitYPosition);
    CGRect lowerSplitRect = CGRectMake(0, splitYPosition, fullScreenRect.size.width, fullScreenRect.size.height-splitYPosition);


    CGImageRef upperImageRef = CGImageCreateWithImageInRect([f CGImage], upperSplitRect);
    UIImage *upperCroppedImage = [UIImage imageWithCGImage:upperImageRef];
    CGImageRelease(upperImageRef);

    CGImageRef lowerImageRef = CGImageCreateWithImageInRect([f CGImage], lowerSplitRect);
    UIImage *lowerCroppedImage = [UIImage imageWithCGImage:lowerImageRef];
    CGImageRelease(lowerImageRef);


    UIImageView *upperImage = [[UIImageView alloc]initWithFrame:upperSplitRect];
    upperImage.image = upperCroppedImage;
    //first.contentMode = UIViewContentModeTop;

    UIView *upperBoarder = [[UIView alloc]initWithFrame:CGRectMake(0, splitYPosition, fullScreenRect.size.width, 1)];
    upperBoarder.backgroundColor = [UIColor whiteColor];
    [upperImage addSubview:upperBoarder];


    UIImageView *lowerImage = [[UIImageView alloc]initWithFrame:lowerSplitRect];
    lowerImage.image = lowerCroppedImage;
    //second.contentMode = UIViewContentModeBottom;

    UIView *lowerBoarder = [[UIView alloc]initWithFrame:CGRectMake(0, 0, fullScreenRect.size.width, 1)];
    lowerBoarder.backgroundColor = [UIColor whiteColor];
    [lowerImage addSubview:lowerBoarder];

    int reveledViewYPosition = splitYPosition;

    if(splitDirection==SplitDirectionUp){
        reveledViewYPosition = splitYPosition - revealedViewHeight;
    }


    UIView *revealedView = [[UIView alloc]initWithFrame:CGRectMake(0, reveledViewYPosition, fullScreenRect.size.width, revealedViewHeight)];
    revealedView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];


    [self.view addSubview:revealedView];
    [self.view addSubview:upperImage];
    [self.view addSubview:lowerImage];

    [UIView animateWithDuration:splitAnimationTime animations:^{
        if(splitDirection==SplitDirectionUp){
            upperImage.center = CGPointMake(upperImage.center.x, upperImage.center.y-revealedViewHeight);
        } else { //assume down
            lowerImage.center = CGPointMake(lowerImage.center.x, lowerImage.center.y+revealedViewHeight);
        }
    }];
}

This means I can call it like this:

[self split:SplitDirectionUp atYPostition:500 withRevealedViewHeight:200];

I used these conveniance functions in the updated split function:

- (CGRect)getScreenFrameForCurrentOrientation {
    return [self getScreenFrameForOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

- (CGRect)getScreenFrameForOrientation:(UIInterfaceOrientation)orientation {

    UIScreen *screen = [UIScreen mainScreen];
    CGRect fullScreenRect = screen.bounds;
    BOOL statusBarHidden = [UIApplication sharedApplication].statusBarHidden;

    //implicitly in Portrait orientation.
    if(orientation == UIInterfaceOrientationLandscapeRight || orientation ==  UIInterfaceOrientationLandscapeLeft){
        CGRect temp = CGRectZero;
        temp.size.width = fullScreenRect.size.height;
        temp.size.height = fullScreenRect.size.width;
        fullScreenRect = temp;
    }

    if(!statusBarHidden){
        CGFloat statusBarHeight = 20;
        fullScreenRect.size.height -= statusBarHeight;
    }

    return fullScreenRect;
}

and this enum:

typedef enum SplitDirection
{
    SplitDirectionDown,
    SplitDirectionUp
}SplitDirection;

Adding a return to normaal function and adding the arrow would be a great addition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文