如何实现连续拖拽菜单效果?

2023-12-03

我正在尝试实现拖放菜单效果。我不知道该怎么做,也许有人有这种确切效果的经验。

很简单,当用户触摸菜单项时,我希望在他们触摸的位置出现一个图形。他们的触摸现在将控制图形的平移。释放触摸后,图形将位于其位置并呈现完整的 Alpha。

我已经熟悉创建平移手势和实例化图形。到目前为止,我可以创建触摸菜单项的图形。最大的问题是我如何“传递”触摸手势,使其成为单一且连续的动作。

另外,菜单项应该是 UIButton 还是 UIImageView?

Any help appreciated. Thanks enter image description here


我对这个很感兴趣。以下代码将在触摸时从按钮抓取图像,将该图像拖动到 alpha=0.5 处,然后将其放在触摸结束处 alpha=1.0 处。此后它将继续可拖动。

导入 QuartzCore 后,创建一个新文件。 .h 应为:

#import <Foundation/Foundation.h>
#import <QuartzCore/CAGradientLayer.h>
#import <QuartzCore/CALayer.h>

@interface DraggableImage : CAGradientLayer

- (void)draw:(UIImage *)image;

- (void)moveToFront;

- (void)appearDraggable;

- (void)appearNormal;

@end

.m 应为:

#import "DraggableImage.h"

@implementation DraggableImage

- (void)draw:(UIImage *)image{
    CGRect buttonFrame = self.bounds;
    int buttonWidth = buttonFrame.size.width;
    int buttonHeight = buttonFrame.size.height;
    UIGraphicsBeginImageContext( CGSizeMake(buttonWidth, buttonHeight) );
    [image drawInRect:self.bounds];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [newImage drawInRect:self.bounds];
}

- (void)moveToFront {
    CALayer *superlayer = self.superlayer;
    [self removeFromSuperlayer];
    [superlayer addSublayer:self];
}

- (void)appearDraggable {
    self.opacity = 0.5;
}


- (void)appearNormal {
    self.opacity = 1.0;
}

@end

现在在主视图控制器中添加:

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "DraggableImage.h"

@interface YourViewController : UIViewController{
    DraggableImage *heldImage;
    DraggableImage *imageForFrame[5]; // or however many
    UIButton *buttonPressed;
    int imageCount;
}
@property (weak, nonatomic) IBOutlet UIButton *imageButton;
-(IBAction)buildImageLayerForButton:(UIButton *)sender;
- (void)moveHeldImageToPoint:(CGPoint)location;
- (CALayer *)layerForTouch:(UITouch *)touch;

在这种情况下,imageButton 将是您的苹果按钮。现在在您的 .m 文件中添加以下内容:

@synthesize imageButton;

#pragma - mark Touches

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    CALayer *hitLayer = [self layerForTouch:[touches anyObject]];
    if ([hitLayer isKindOfClass:[DraggableImage class]]) {
        DraggableImage *image = (DraggableImage *)hitLayer;

        heldImage = image;
        [heldImage moveToFront];
    }
    hitLayer = nil;
    [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

        if (heldImage) 
        {
            UITouch *touch = [touches anyObject];
            UIView *view = self.view;
            CGPoint location = [touch locationInView:view];
            [self moveHeldImageToPoint:location];
        }

}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    if (heldImage) {
        [heldImage appearNormal];
        heldImage = nil;
    }
}

- (void)dragBegan:(UIControl *)c withEvent:ev {
}
- (void)dragMoving:(UIControl *)c withEvent:ev {
    UITouch *touch = [[ev allTouches] anyObject];
    CGPoint touchPoint = [touch locationInView:self.view];
    [self moveHeldImageToPoint:touchPoint];
}

- (void)dragEnded:(UIControl *)c withEvent:ev {
    UITouch *touch = [[ev allTouches] anyObject];
    CGPoint touchPoint = [touch locationInView:self.view];
    [self moveHeldImageToPoint:touchPoint];
    [heldImage appearNormal];
    heldImage = nil;
}



-(IBAction)buildImageLayerForButton:(UIButton *)sender{


        DraggableImage *image = [[DraggableImage alloc] init];
        buttonPressed = sender;
        CGRect buttonFrame = sender.bounds;
        int buttonWidth = buttonFrame.size.width;
        int buttonHeight = buttonFrame.size.height;

        image.frame = CGRectMake(120, 24, buttonWidth*3, buttonHeight*3);
        image.backgroundColor = [UIColor lightGrayColor].CGColor;
        image.delegate = self;
        imageForFrame[imageCount] = image;
        [self.view.layer addSublayer:image];
        [image setNeedsDisplay];
        [image moveToFront];
        [image appearDraggable];
        heldImage = image;
        [self moveHeldImageToPoint:sender.center];

        imageCount++;

}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    UIGraphicsPushContext(ctx);

    DraggableImage *image = (DraggableImage *)layer;
    [image draw:[buttonPressed imageForState:UIControlStateNormal]];

    UIGraphicsPopContext();
}

- (void)moveHeldImageToPoint:(CGPoint)location 
{
    float dx = location.x;
    float dy = location.y;
    CGPoint newPosition = CGPointMake(dx, dy);

    [CATransaction begin];
    [CATransaction setDisableActions:TRUE];
    heldImage.position = newPosition;
    [CATransaction commit];
}

- (CALayer *)layerForTouch:(UITouch *)touch 
{
    UIView *view = self.view;

    CGPoint location = [touch locationInView:view];
    location = [view convertPoint:location toView:nil];

    CALayer *hitPresentationLayer = [view.layer.presentationLayer hitTest:location];
    if (hitPresentationLayer) 
    {
        return hitPresentationLayer.modelLayer;
    }

    return nil;
}

-(void)viewDidLoad{
    [imageButton addTarget:self action:@selector(dragBegan:withEvent:) forControlEvents: UIControlEventTouchDown];
    [imageButton addTarget:self action:@selector(dragMoving:withEvent:) forControlEvents: UIControlEventTouchDragInside | UIControlEventTouchDragOutside];
    [imageButton addTarget:self action:@selector(dragEnded:withEvent:) forControlEvents: UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
    [super viewDidLoad];
}

- (void)viewDidUnload {
    [self setImageButton:nil];
    [super viewDidUnload];
}

等等瞧!连接您的按钮,设置其图像,然后将副本扔到整个屏幕上。 :)

注:我没有发表太多评论,但很乐意回答任何问题。

Cheers!

编辑:修复了-(void)draw:(UIImage *)image{}以便它可以正确调整图像大小。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何实现连续拖拽菜单效果? 的相关文章

  • “EXC_BAD_ACCESS”与“分段错误”。两者实际上相同吗?

    在我的前几个虚拟应用程序 用于学习时练习 中 我遇到了很多EXC BAD ACCESS 这以某种方式告诉我错误访问是 您正在触摸 访问一个不应该的对象 因为它尚未分配或释放 或者只是您无权访问它 查看此示例代码 该代码存在访问错误问题 因为
  • 如何在 iOS 上更改设备音量 - 而不是音乐音量

    我想更改 iOS iPhone 上的设备音量 我知道我可以使用以下几行更改音乐库的音量 implement at first MediaPlayer framework MPMusicPlayerController musicPlayer
  • 解析迁移到 mLabs 和 Heroku 的错误

    我至少一年前将解析数据库迁移到 Mlabs 从那时起我就一直在开发该应用程序 解析仪表板表示我已成功迁移 Mlab 和 Parse 都收到了数据库的更新 然而 在过去一两周内 该应用程序不再经过登录页面 没有调整代码 这是服务器问题 以下是
  • 如何计算CLLocationDistance的中心坐标

    我想计算我的位置和一些注释之间的中心点 到目前为止我已经这样做了 CLLocation myLoc self locMgr location MKPointAnnotation middleAnnotation locationV anno
  • 是否可以对 UILabel 的文本颜色变化进行动画处理? [复制]

    这个问题在这里已经有答案了 UIView animateWithDuration 5 animations myLabel textColor UIColor redColor 标签文本颜色立即改变 Try this UIView tran
  • 为什么我无法更改 UIBarButtonItem 的标题?

    我想改变UIBarButtonItem s title 但这段代码不起作用 void viewDidLoad self smay void smay AppDelegate apd AppDelegate UIApplication sha
  • 在两个可移动 uiview 之间画线

    我有一个带有节点的 滚动视图 UIViews 可以拖动 我正在尝试在选定的之间绘制边缘UIViews使用 calayer 但我不知道当视图位置发生变化时如何重新绘制线条 In my viewControllerI 类在节点数组中添加第一个和
  • UINavigationBar 滑开而不是留在原处

    我创建了演示项目来展示问题 我们在 UINavigationController 中有两个视图控制器 MainViewController这是根 class MainViewController UIViewController lazy
  • 如何让位置音频在 SceneKit 中工作?

    我在使位置音频在 SceneKit 中工作时遇到问题 从 Xcode 生成的 SceneKit 游戏模板开始 我将以下代码添加到handleTap 方法的末尾 let ship scnView scene rootNode childNod
  • 使用基于 Cookie 的身份验证的 Capacitor iOS

    我正在使用 Capacitor v3 NextJS 静态导出和 Django 后端基于生产网站构建 iOS 应用程序 当前的后端身份验证方案通过 cookie 使用 Django 会话 并通过 cookie 设置 CSRF 令牌 应用程序可
  • Cocoa App 中使用#include 编译错误

    我正在尝试在 xcode 4 0 中编译 Cocoa 应用程序 但收到此错误 fatal error string file not found 当尝试在这一行编译为 pch 文件时 include
  • 在后台继续下载

    我正在创建一个应用程序 其中我从服务器下载一些数据 在后台运行时 我希望连接继续运行 以便可以下载数据 我知道有方法应用程序委托 void applicationDidEnterBackground UIApplication applic
  • 如何使用固定宽度和自动布局正确缩放图像?

    我有一个动态 UIImage 和一个固定宽度为 280 0px 的 UIImageView 并且我正在使用自动布局 在 UIImage 视图上 我设置了宽度和高度约束 并降低了高度约束的优先级 我选择了 aspect fit 并将内容拥抱和
  • 如何将NSTextView的格式化内容转换为字符串

    我需要将 NSTextView 的内容从 Mac 应用程序传输到 iOS 应用程序 我使用 XML 作为传输文件格式 所以我需要将 NSTextView 的内容 文本 字体 颜色等 保存为字符串 有什么办法可以做到这一点吗 一种方法是存档
  • 如何在没有 MFMessageComposeViewController 的情况下发送和接收短信?

    我想发送和接收短信而不显示MFMessageViewController从我的申请中 有人能告诉我这怎么可能吗 不可能 除非您使用第 3 方 api 发送 接收短信
  • 使用自定义格式将字符串转换为 NSDate [重复]

    这个问题在这里已经有答案了 可能的重复 NSString 到 NSDate https stackoverflow com questions 1353081 nsstring to nsdate iPhone 如何将 yyyyMMddTh
  • iOS 11 中的密码自动填充快速输入栏

    iOS 11 中引入了一项新功能 应用程序密码自动填充 此功能允许用户直接从键盘快速输入栏使用其应用程序中保存的密码 https techcrunch com 2017 06 08 ios 11s new password autofill
  • GCD 与自定义队列

    我想知道这两者的性能有什么区别 dispatch async dispatch get global queue DISPATCH QUEUE PRIORITY HIGH 0 perform complex operation dispat
  • iOS 11 特定设置部分的 URL 方案停止工作

    我的应用程序使用 URL 方案将用户直接带到 设置 常规 关于 部分 以下 URL 在 10 3 x 中工作正常 应用程序首选项 根 常规 路径 关于 然而 这个 URL 方案在 iOS 11 GM 版本中不再有效 它仅启动 设置 应用程序
  • 构建 iOS 应用程序后退出代码 1 错误

    我正在尝试使用 RestKit 构建我的项目 当我构建它时 我收到以下错误 我尝试使用 Apple LLVM 3 0 和 LLVM GCC 4 2 进行编译 两者都产生相同的结果 任何人有任何想法是什么导致了这个问题 Ld Users Ji

随机推荐

  • WSO2 ESB 4.8.1 中支持的 XPath 函数

    WSO2 ESB 4 8 1 似乎不支持以下 XPath 函数 escape html uri iri 到 uri 编码为 uri 有谁知道 WSO2 ESB 4 8 1 支持哪些 XPath 函数以及不支持哪些函数 Answer reco
  • 将图像(覆盖)放置在另一个图像(背景)的 x,y 上

    我需要在运行时动态地将图像放置在另一个图像上 精确地位于背景图像的 x y 位置 我有以下详细信息 叠加图像属性 红色 x 58 y 232 h 266 w 431背景图片 黑色 match parent w 1024 h 768 这里 x
  • 训练后如何获取神经网络参数?

    我正在使用 matlab 的神经网络进行分类 我想知道如何存储网络参数 例如 纪元 时间 MSE等 训练后在矩阵中 多谢 打电话时train 第二个返回的参数是培训记录 其中包含有关训练的纪元 时间和其他信息 例如 net tr train
  • 检查未知对象中的对象是否存在的最有效的Javascript方法[重复]

    这个问题在这里已经有答案了 这是我在 Javascript 中经常遇到的事情 假设我有一个这样的对象 var acquaintances types friends billy 6 jascinta 44 john 91 others Ma
  • 詹金斯下的git克隆/ssh

    我使用 stash 作为 git 存储库管理器 stash 使您能够为每个尝试连接和克隆的用户添加 ssh 密钥 我已经为所有 UNIX 用户配置好了 但 Windows 却给我带来了困难 Windows 从机 2008 R2 服务器 上的
  • 自定义视图矩阵的拉伸问题

    我目前正在为我的项目开发自己的二维数学库 以提高我对底层矩阵数学的理解 过去我使用过 GLM 等库 但我觉得它可能值得研究作为一种学习经验 其中大部分都很简单 我的大多数数学课程都与 OpenGL 集成并运行良好 但是我的视图矩阵似乎在窗口
  • 使用字符串访问变量

    我目前有一个 Javascript 函数 它使用字符串来引用对象名称并访问其属性 我目前正在使用 eval 来获得所需的效果 我知道这是非常非常错误的 这是我目前如何实现我想要的目标的示例 var stringToObjectRef fun
  • iPhone上取消控制播放音乐时如何设置标题?

    我正在开发一个广播应用程序 它支持在后台播放音乐 但我陷入了如何设置音乐标题以取消控制的困境 The difference between my app and Music is as following 我应该怎么做才能让我的应用程序显示
  • 使用 RSA 密钥保护许可证密钥

    已经很晚了 我很累 而且可能很沉 我编写了一个需要保护的应用程序 因此它只能在我为其生成密钥的计算机上运行 我现在正在做的是获取 BIOS 序列号并从中生成哈希值 然后使用 XML RSA 私钥对其进行加密 然后我对 XML 进行签名以确保
  • 访问自定义数据注释内的依赖属性的简单方法

    我的上有以下属性DomainRegistry model Domain Extension public string Name get set Required ErrorMessage Select extension public s
  • Java字符串-将多个空格替换为一个,然后根据空格将字符串拆分为数组[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 假设我有一个字符串 s 2323 2323 232 3232 0 2 0 3 3232
  • 不在范围内:数据构造函数

    我写了一个程序haskell但我从 ghci 收到错误 这是源代码 我构建它 如果我有 p1 Prop p1 And Var A Not Var A 它将显示A A这就是源代码 import Data List import Data Ch
  • GMT 与本地时间转换(夏令时更改)

    我从服务器接收 GMT 时间结构 用户定义的结构 使用它我想将其转换为本地时间 我通过用接收到的结构填充 NSDate 组件来完成此操作 然后我使用日期格式化程序从中获取日期它 除了一种情况外 一切正常 如果 GMT 时间在 11 月 3
  • 替换文本文件中的模式

    下面是我的示例 html 文件 some text here img src http site com 7b399e20 77165 5fa 2a31ffb8 jpg sometext here some text here img sr
  • 如何使用 Yocto SDK 构建 Linux 内核模块?

    我正在尝试使用 Yocto SDK 构建 Linux 内核模块 但是 我遇到了编译错误 它抱怨 include uapi asm generic int ll64 h 12 10 fatal error asm bitsperlong h
  • 修改密码后无法登录mysql 5.7.9

    我已经安装了MysqlVer 14 14 Distrib 5 7 9 适用于 Linux x86 64 使用 EditLine 包装器 On CentOS Linux 版本 7 1 1503 我使用以下命令更改了 root 密码 alter
  • 为新的输入字符串重用 Antlr 对象(C++ 运行时)?

    我已经使用 C 运行时演示构建了一个基本解析器 并且运行良好 但是 我通常会解析大量输入字符串 是否可以修改代码以重用现有对象进行重复调用 如果是这样 有人有这方面的例子吗 是的 可以重复使用这些对象 解析调用的典型序列如下所示 input
  • XMLHttpRequest 读取外部文件

    我想通过 JavaScript 在客户端浏览器上运行 检索文本文件 从给定 URL 中包含的数据 到目前为止 我已经尝试过以下方法 var xmlhttp text xmlhttp new XMLHttpRequest xmlhttp op
  • 如何访问 SQL2005 Profiler 中的 Context_Info() 变量?

    我使用 Context Info 变量来跟踪正在执行存储过程和自由格式 SQL 的用户 对此服务器上的问题进行故障排除时 每个会话都会通过 我希望能够引入 context info 变量的值并基于它进行过滤 在设置 context info
  • 如何实现连续拖拽菜单效果?

    我正在尝试实现拖放菜单效果 我不知道该怎么做 也许有人有这种确切效果的经验 很简单 当用户触摸菜单项时 我希望在他们触摸的位置出现一个图形 他们的触摸现在将控制图形的平移 释放触摸后 图形将位于其位置并呈现完整的 Alpha 我已经熟悉创建