创建具有删除功能的自定义 UIButton 类

2024-01-08

我有一个 UIButtons 网格。当我点击“编辑”按钮时,我希望每个按钮上都出现一个删除按钮,按下该按钮时,会删除该按钮(以及关联的数据)。有点像苹果的主屏幕,当你按住一个按钮时,它就会开始摆动,角落里有一个 X。

根据这篇文章:子类 UIButton 添加属性 https://stackoverflow.com/questions/5500327/subclass-uibutton-to-add-a-property我可以使用关联引用为每个按钮添加属性。我尝试添加一个 UIButton 作为我的自定义 UIButton 的属性,但我似乎无法让它出现,并且感觉这不是正确的方法。这是我的自定义按钮主要:

    #import "UIButton+Property.h"
#import <objc/runtime.h>

@implementation UIButton(Property)

static char UIB_DELETEBUTTON_KEY;

@dynamic deleteButton;


- (void)setDeleteButton:(UIButton *)deleteButton {
    deleteButton = [UIButton buttonWithType:UIButtonTypeInfoDark];
    deleteButton.frame = CGRectMake(100, 100, 50, 50);
    objc_setAssociatedObject(self, &UIB_DELETEBUTTON_KEY, deleteButton, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIButton *)deleteButton {
    return (UIButton *)objc_getAssociatedObject(self, &UIB_DELETEBUTTON_KEY);
}

@end

这是我以编程方式添加按钮的地方:

//Create a custom button for each custom book doc
for (int i = 0; i < [customBookDocs count]; ++i) {
    BookDoc *customBookDoc = [customBookDocs objectAtIndex:i];
    NSString *bookTitle = customBookDoc.book.title;

    //create a button for each book
    CGRect frame = CGRectMake(xCoord, yCoord, 200, 200);
    UIButton *bookButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    bookButton.bookDoc = customBookDoc;
    [bookButton setFrame:frame];
    [bookButton setTitle:bookTitle forState:UIControlStateNormal];
    [bookButton addTarget:self action:@selector(bookButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    xCoord += 250;

    [self.view addSubview:bookButton];
    [self.view addSubview:bookButton.deleteButton];
}

有没有更简单更明智的方法来做到这一点?或者我走在正确的轨道上吗?


最初的回应开始:

...其他人可能对此有更多要说的,但我不确定为什么您需要在这里使用对象关联。您当然可以使用常规子类化将另一个按钮作为属性添加到按钮中,这就是我将采取的路线。 ...

编辑如下:

我以为我直接子类化了一个UI控件,但是当我去寻找代码时我发现我错了。 @Joe 在评论中正确地指出直接子类化 UI 控件存在问题。

通过创建一个包装类来保存按钮及其相关的删除按钮,我能够在不使用关联对象的情况下实现类似您所描述的功能。它可以工作,但不是很灵活,所以我通常会推荐@Joe 的方法作为更好的解决方案。

这是相关代码:

为了简单起见,我将所有代码都放入了 appDelegate 中。我不建议在现实生活中这样做。

AppDelegate.m:

@implementation AppDelegate

@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    self.window.backgroundColor = [UIColor whiteColor];

    UIButton *toggleDeleteButtons = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [toggleDeleteButtons setFrame:CGRectMake(20, 45, 280, 45)];
    [toggleDeleteButtons setTitle:@"Toggle Delete" forState:UIControlStateNormal];
    [toggleDeleteButtons addTarget:self action:@selector(toggleDeleteButtonAction) forControlEvents:UIControlEventTouchUpInside];
    [[self window] addSubview:toggleDeleteButtons];

    ButtonWrapper *myButtonWrapper = [[ButtonWrapper alloc] init];
    [[myButtonWrapper button] setFrame:CGRectMake(20, 100, 200, 45)];
    [[myButtonWrapper button] setTitle:@"This is my button" forState:UIControlStateNormal];
    [[myButtonWrapper deleteButton] addTarget:self action:@selector(buttonDeleteRequested:) forControlEvents:UIControlEventTouchUpInside];
    [[myButtonWrapper deleteButton] setTag:0];
    [[self window] addSubview:[myButtonWrapper button]];
    buttonWrapper1 = myButtonWrapper;

    // Added instance called anotherButtonWrapper with tag 1, as above

    // Added instance called stillAnotherButtonWrapper with tag 2, as above

    [self.window makeKeyAndVisible];
    return YES;
}

- (void)toggleDeleteButtonAction {
    static BOOL deleteButtonsShown;

    [buttonWrapper1 showDeleteButton:!deleteButtonsShown];
    [buttonWrapper2 showDeleteButton:!deleteButtonsShown];
    [buttonWrapper3 showDeleteButton:!deleteButtonsShown];
    deleteButtonsShown = !deleteButtonsShown;
}

- (void)buttonDeleteRequested:(UIButton *)deleteButton {
    // delete the specified button here
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Delete" message:[NSString stringWithFormat:@"Delete was pressed on button %i",[deleteButton tag]]delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}

ButtonWrapper.m:

@implementation ButtonWrapper

@synthesize button;
@synthesize deleteButton;

- (ButtonWrapper *)init {
    ButtonWrapper *newWrapper = [ButtonWrapper alloc];

    UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [myButton setFrame:CGRectZero];

    UIButton *myDeleteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [myDeleteButton setFrame:CGRectMake(0, 0, 100, 40)];
    [myDeleteButton setTitle:@"Delete" forState:UIControlStateNormal];
    [myDeleteButton setHidden:TRUE];
    [myButton addSubview:myDeleteButton];

    [newWrapper setButton:myButton];
    [newWrapper setDeleteButton:myDeleteButton];

    return newWrapper;
}

- (void)showDeleteButton:(BOOL)showButton {
    if (showButton) {
        [[self deleteButton] setHidden:FALSE];
        [[self deleteButton] setEnabled:TRUE];    }
    else {
        [[self deleteButton] setHidden:TRUE];
        [[self deleteButton] setEnabled:FALSE];
    }
}
@end

该解决方案不需要我实现所有 UI 属性,但它确实需要额外的工作来连接嵌入式委托,这很麻烦。可能有一种方法可以在初始化时将委托传递到包装器中,但我无法使其工作。

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

创建具有删除功能的自定义 UIButton 类 的相关文章

  • Firebase 查询 - 查找包含字符串的子项

    我在使用 Firebase 查询时遇到了一些问题 我想查询对象 其中对象子值包含特定字符串 到目前为止 我有一些看起来像这样的东西 Firebase ref Firebase alloc initWithUrl https dinosaur
  • UITableView 部分始终保持在视图内

    我有一个包含 3 个部分的 UITableView 第 1 节 该部分的标题是 Players 内容恰好是 1 个单元格 包含 1 4 个玩家姓名的水平列表 第 2 节 该部分的标题是 回合 内容是 X 个单元格 每个单元格包含每个玩家在第
  • Xcode - 重命名项目会导致问题

    我目前正在开发 iPhone 应用程序 我从在互联网上找到的项目模板开始研究这个问题 现在我想重命名这个项目 我已经成功重命名了实际的项目文件 文件夹和可执行文件以及其他一些东西 但有一个奇怪的问题 如果我尝试在 iPhone 设备上运行该
  • 如何使用 Swift 将 UIImageView 设置在屏幕中心水平或垂直,但不再使用 StoryBoard

    我正在尝试放置一个UIImageView屏幕上方中央水平方向 正在编码viewDidLoad 而且我有两个预案 这意味着我不知道具体的功能或API 1 我想设置一个等于屏幕宽度一半的变量 我知道它会与 边界 或 框架 相关的东西一起工作 可
  • 如何在代码中的UIToolBar中添加UIBarButtonItem

    我有标准 UIBarButtonItem UIBarButtonItem share UIBarButtonItem alloc initWithBarButtonSystemItem UIBarButtonSystemItemAction
  • iPhone 录音时不振动

    我正在修改 AurioTouch 示例 我想振动手机以响应特定的声音输入 我可以检测输入并printf他们 但是AudioServicesPlaySystemSound kSystemSoundID Vibrate 会话期间不执行任何操作k
  • iOS 11 /“Apps-prefs=root”功能在更新到 Swift 3 后不起作用

    我对 Swift 编程还很陌生 我制作了一个简单的测试应用程序 可以通过特定按钮以编程方式打开设置 不幸的是 更新按钮后 没有打开所需的设置页面 在本例中为 wifi 页面 而是仅打开通用设置屏幕 有人可以帮助我了解 swift 4 中究竟
  • 框架链接错误,找不到图像?

    我在我的应用程序中使用 DarwiinRemote 的 WiiRemote framework 我已经通过下载源代码并要求垃圾收集以及针对 10 5 进行构建来修复了一些问题 但是 当我尝试将其添加到我的项目时 我收到控制台错误 dyld
  • 使用 Xcode 资产目录缓存 UIImage

    我们都知道UIImage神秘的幕后缓存机制imageNamed 方法 在苹果的UIImage 类参考 https developer apple com library IOS documentation UIKit Reference U
  • 识别用户是否在 iOS 6 设置中定义了本机 Facebook 帐户

    有没有办法通过 FACEBOOK SDK 3 1 和 iOS 6 知道用户是否在 iPhone 设置中定义了其 Facebook 帐户以供本机 Facebook 使用 我想要做的是 当打开我的应用程序时 如果用户在 iPhone 设置中定义
  • Cordova 构建 iOS 应用程序并打开模拟器,但未安装

    我正在 MacOS 上用 Cordova 制作一个 iOS 应用程序 当我跑步时cordova emulate ios该应用程序会构建并打开 iPhone X iOS 11 4 的模拟器 但它从未在模拟器中安装该应用程序 它仅显示模拟器主屏
  • MVVM 在 iOS 中的使用

    我是一名 iOS 开发人员 我对我的项目中存在大量视图控制器感到内疚 因此我一直在寻找更好的方法来构建我的项目 并遇到了 MVVM 模型 视图 视图模型 架构 我读了很多关于 iOS 的 MVVM 文章 但有几个问题 我将用一个例子来解释我
  • iOS 框架问题:类在两者中均实现

    我正在开发一个使用第三方框架类的iOS框架项目 所以我在下面添加了第三方框架链接的框架和库部分 当我在 iOS 应用程序项目中添加自定义框架时 每个类都会收到此警告 objc 3139 类 class name 在两者中均实现 privat
  • Measure 应用程序是否有可用的 URL 方案?

    我想推出新的测量应用程序 在 iOS 12 上 在我的应用程序中 这可能吗 应用程序是否有可用的 URL 方案可用于此目的 或者还有其他方法可以做到吗 Thanks 您似乎无法打开此应用程序 In the 文档存档 https develo
  • 通过更改其优先级值来动画布局约束

    我有一个包含大量文本的标签 有一个用于折叠和展开标签高度的切换开关 此处名为 里拉套房 所以它会截断文本的结尾 我精心设置了垂直内容拥抱优先级和压缩阻力 因此内在尺寸比压缩阻力具有更高的优先级 高度限制 直接位于标签右侧的可选约束 设置为常
  • iOS应用程序启动黑屏,UINavigationController,Nib,RootViewController

    我有以下应用程序 其RootViewController被命名TopicsViewController 当我运行它时 没有任何错误或中断 但屏幕是black 没有桌子 无论是有人的还是空的 只有黑屏 不确定发生了以下哪一种情况 我的申请有问
  • 在 Objective C 中读取解析 XML 的 CDATA 部分

    我正在研究一个关于解析 google 天气 api 的 iphone 示例教程 该 api 似乎不再存在 所以我找到了一个替代方案 本教程使用 libxml2 和 xpath 查询来解析 xml 文件 我成功解析了大部分数据 我遇到的问题是
  • iOS Javascript 引擎 parseFloat(1) 返回负数

    这段代码将使错误出现 function causeBug d var k var n parseFloat 1 var c Math abs d if n lt 0 k else k return k n function for var
  • 如何在 Swift 中的标签上制作阴影效果?

    我不知道如何在标签上编写阴影代码 我有一个会改变的乐谱标签 因此无法仅对带有阴影的文本进行Photoshop处理 我需要对其进行编码 以便它始终自动在文本后面有一个模糊的阴影 有人可以举一些例子或提供帮助吗 人们说这是重复的 重复 是关于
  • 如何从我的 appDelegate 访问我的 viewController? iOS系统

    我有一个在 xCode 中创建为 基于视图的应用程序 的 iOS 应用程序 我只有一个 viewController 但它会自动显示 而且我没有看到任何将它与我的 appDelegate 关联的代码 我需要将数据从 appDelegate

随机推荐

  • 收到fcm通知后自动开始活动吗?

    我想在收到 fcm 推送通知后自动启动特定活动 单击时效果很好 但我想在收到通知后自动启动它 这是我的代码 我触发代码的 FirebaseMessagingService 方法 public class MyFirebaseMessagin
  • 头文件中的静态 const 变量声明

    如果我在头文件中声明 static const 变量 如下所示 static const int my variable 1 然后将此标头包含在多个标头中 c文件 编译器将为每个文件创建新实例 或者足够 聪明 地看到它是const并且只会为
  • 从 PowerShell 使用 System.IO 访问 MTP 存储

    我正在尝试访问 MTP 设备存储以自动执行文件复制 备份等 如果 Windows 资源管理器能够打开并浏览 Android 设备内部存储和连接的 SD 卡 我如何使用 PowerShell 访问这些存储 我发现了很多提示 例如 获取设备 I
  • Java泛型中如何获取类型变量的类

    我见过类似的问题 但没有多大帮助 例如我有这个通用类 public class ContainerTest
  • 使用区域在 UML 活动图中循环

    我正在 UML 活动图中对循环进行建模 它适用于简单的条件节点 图 1 但我正在寻找一种更具表现力的方法来强调循环语义 所以我来到了所示的 区域 或 可中断区域 here http www pst ifi lmu de stoerrle V
  • 导入错误:DLL 加载在 Jupyter 笔记本中失败,但在 .py 文件中工作

    我安装了突破检测 https github com roland hochmuth BreakoutDetectionAnaconda 环境中的模块 当我尝试使用导入模块时import breakout detection在 jupyter
  • 如何在 MATLAB 中删除向量中一组索引处的元素?

    我有一个包含 100 个元素的向量 我有另一个向量 其中包含我想要从此向量中删除的元素的索引位置 我该怎么做呢 vector indecies example gt gt a 1 10 gt gt a 3 4 7 a 1 2 5 6 8 9
  • 为什么贪心算法找不到二分图的最大独立集?

    我试图使用贪心法解决二分图上的最大独立集问题 所以发现这篇文章正是我想做的 但我只关注二分图 答案中的反例不是二部图 是否有任何二分图无法使用 Greedy G S While G is not empty Let v be a node
  • 将 Google Analytics 与 Require.js 结合使用时出现问题

    我正在使用 require js http requirejs org http requirejs org 对于我网站上的许多功能 到目前为止它似乎运行良好 不过 我在尝试包含 Google Analytics 代码时遇到了问题 该代码似
  • php 的分支预测

    刚刚读了一篇很棒的文章分支预测 https stackoverflow com questions 11227809 why is processing a sorted array faster than an unsorted arra
  • 为什么Maven打出来的包没有附带依赖?

    我已经按照最简单的 Maven 示例 https maven apache org guides getting started maven in five minutes html并做出以下内容pom xml file
  • C#:'is' 关键字并检查 Not

    这是一个愚蠢的问题 但您可以使用此代码来检查某些东西是否是特定类型 if child is IContainer 有没有更优雅的方法来检查 NOT 实例 if child is IContainer A little ugly silly
  • 如何使用 EF Core 3.1 将 IEnumerable 的属性存储在 Cosmos 表中

    我的项目使用 EF Core 3 1 并以 Azure Cosmos 作为数据库 我有一个这样的实体 public class MyEntity public IEnumerable
  • 使用 Flask-admin 将文件附加到模型

    我正在使用 Flask Admin 为网站提供管理界面 如何处理文件上传到 sqlalchemy 模型 例如 class Product db Model tablename products id db Column db Integer
  • 如何从 Postgres 的预订中查找第一个免费开始时间

    人们的工作时间为上午 10 00 至晚上 21 00 周日和公共假期除外 每隔 15 分钟为他们预留一个工作岗位 工作时间为15分钟至4小时 整个工作必须适合一天 如何查找从当前日期和时间开始在 Postgres 9 3 中未在给定持续时间
  • 使用 npm 运行 bash 脚本

    我想尝试使用 npm 运行 Web 应用程序的各种构建任务 我知道我可以通过添加一个来做到这一点scripts领域到我的package json像这样 scripts build some build command 当您有更复杂的命令和一
  • 创建一个可以按任意顺序包含 int 和 string 的类型

    我正在关注这个哈斯克尔简介 http www cs auckland ac nz references haskell haskell intro html goodies html 而这个特定的地方 用户定义类型 2 2 我发现特别晦涩难
  • 已删除的实体传递给持久异常

    我有这样的实体 文档 恩 到 1 文件类型 1 到 n 财产种类 1 到 n 文件属性 我只是尝试删除如下文档 实体管理器 删除 文档 但发生错误 16 45 51 499 错误 Seam Resource Servlet servlet
  • Eclipse(带 adt)不会看到/识别正在运行的 avd

    我已经尝试这个一周左右了 我已经按照教程让 hello android 工作了 但是当 AVD 启动时 程序无法运行 我正在运行 Windows 7 64 位和 eclipse 3 5 2 运行 adt 0 9 9 和 SDK r7 sdk
  • 创建具有删除功能的自定义 UIButton 类

    我有一个 UIButtons 网格 当我点击 编辑 按钮时 我希望每个按钮上都出现一个删除按钮 按下该按钮时 会删除该按钮 以及关联的数据 有点像苹果的主屏幕 当你按住一个按钮时 它就会开始摆动 角落里有一个 X 根据这篇文章 子类 UIB