Swift的几种传值方式

2023-11-09

传值方式

在进行页面跳转过程中无法避免需要进行值的传递,那么值的传递可以分为正向传值和反向传值,例如在SourceViewController跳转至DestinationViewController的过程中需把前者的属性值传递给后者称为正向传值;在DestinationViewController进行销毁页面操作时SourceViewController接受到了值并进行UI的改变称为反向传值,以下是能实现传值的几种传值方式。

使用Segue传值

可以使用Segue将数据从一个视图控制器传递到另一个视图控制器。在源视图控制器中,您可以覆盖prepare(for:sender:)方法,并使用destinationViewController属性来获取目标视图控制器。然后,您可以在目标视图控制器中使用自定义属性来获取传递的数据。(这种传值方式是基于storyboard创建的ViewController

以下是一个示例:

假设您有两个视图控制器:ViewControllerDestinationViewController,您想要在这两个视图控制器之间传递一些数据。

首先,在Storyboard中,您需要创建一个Segue,将ViewControllerDestinationViewController连接起来。并设置Segue的标识符为MySegue,如下图所示:

 然后,在ViewController 中,您需要实现prepare(for:sender:) 方法,该方法会在Segue将要发生时被调用。您可以在这个方法中获取DestinationViewController ,并将需要传递的数据设置到DestinationViewController 的属性中,如下所示:

class ViewController: UIViewController {

    let message: String = "我是一个数据"
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "MySegue"{
						// 获取目标视图控制器
            let destinationVC = segue.destination as! DestinationViewController
            // 设置目标视图控制器的属性
						destinationVC.labelText = message
        }
    }

}

在DestinationViewController中,您可以定义一个属性来接收传递的数据。在这个例子中,我们定义了一个labelText属性来接收从ViewController传递过来的数据,如下所示:

class DestinationViewController: UIViewController {
    
    @IBOutlet weak var dataLabel: UILabel!
    var labelText: String = ""
    override func viewDidLoad() {
        super.viewDidLoad()
        dataLabel.text = labelText
        // Do any additional setup after loading the view.
    }
}

使用属性传值

在源视图控制器中,您可以创建一个属性来存储需要传递的数据。然后,您可以将该属性分配给目标视图控制器的相应属性。

以下是一个示例:

假设您有两个视图控制器:SourceViewControllerDestinationViewController,您想要在这两个视图控制器之间传递一些数据。

SourceViewController中,您可以定义需要传递的数据,并将其设置到DestinationViewController的属性中。

// SourceViewController
class SourceViewController: UIViewController {
    // 定义需要传递的数据
    var message: String = "Hello, World!"

    override func viewDidLoad() {
        super.viewDidLoad()

        // 创建DestinationViewController实例
        let destinationVC = DestinationViewController()

        // 将数据设置到DestinationViewController的属性中
        destinationVC.message = message

        // 显示DestinationViewController
        present(destinationVC, animated: true, completion: nil)
    }
}

在DestinationViewController中,您可以定义一个属性来接收传递的数据。在这个例子中,我们定义了一个message属性来接收从SourceViewController 传递过来的数据,如下所示:

// DestinationViewController
class DestinationViewController: UIViewController {
    // 定义用于接收数据的属性
    var message: String = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // 在界面上显示接收到的数据
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 30))
        label.center = view.center
        label.textAlignment = .center
        label.text = message
        view.addSubview(label)
    }
}

使用代理传值

可以创建一个代理协议并在源视图控制器中实现该协议。在目标视图控制器中,您可以设置代理并调用代理方法来传递数据。

以下是一个示例:

假设您有两个视图控制器:SourceViewControllerDestinationViewController,您想要在这两个视图控制器之间传递一些数据。

首先,您需要定义一个代理协议,该协议定义了一个用于传递数据的方法。示例代码如下:

// 定义代理协议
protocol DestinationViewControllerDelegate: AnyObject {
    func destinationViewController(_ controller: DestinationViewController, didPassMessage message: String)
}

然后,在DestinationViewController中,您需要声明一个代理属性,并在需要传递数据的地方调用代理方法。示例代码如下:

// DestinationViewController
class DestinationViewController: UIViewController {
    // 定义代理属性
    weak var delegate: DestinationViewControllerDelegate?

    // 在需要传递数据的地方调用代理方法
    @IBAction func passMessage(_ sender: UIButton) {
        delegate?.destinationViewController(self, didPassMessage: "Hello, World!")
    }
}

在SourceViewController中,您需要实现代理协议,并将SourceViewController设置为DestinationViewController的代理。示例代码如下:

// SourceViewController
class SourceViewController: UIViewController, DestinationViewControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()

        // 创建DestinationViewController实例
        let destinationVC = DestinationViewController()

        // 将SourceViewController设置为DestinationViewController的代理
        destinationVC.delegate = self

        // 显示DestinationViewController
        present(destinationVC, animated: true, completion: nil)
    }

    // 实现代理方法
    func destinationViewController(_ controller: DestinationViewController, didPassMessage message: String) {
        print("Received message: \(message)")
    }
}

这样,在DestinationViewController中调用代理方法时,会触发SourceViewController中实现的代理方法,并将数据传递给SourceViewController。在SourceViewController中,您可以使用传递过来的数据进行后续的处理,例如打印出来。

使用闭包传值

在目标视图控制器中,您可以定义一个闭包来处理传递的数据。然后,在源视图控制器中,您可以将闭包分配给目标视图控制器的相应属性。

以下是一个示例:

 

假设您有两个视图控制器:SourceViewControllerDestinationViewController,您想要在这两个视图控制器之间传递一些数据。

DestinationViewController中,您需要定义一个闭包变量,该闭包变量将用于传递数据。示例代码如下:


// DestinationViewController
class DestinationViewController: UIViewController {
    // 定义闭包变量
    var messageHandler: ((String) -> Void)?

    // 在需要传递数据的地方调用闭包
    @IBAction func passMessage(_ sender: UIButton) {
        messageHandler?("Hello, World!")
        dismiss(animated: true, completion: nil)
    }
}

在SourceViewController中,您可以在创建DestinationViewController实例时,将一个闭包作为参数传递进去,并在闭包中处理从DestinationViewController传递过来的数据。示例代码如下:

// SourceViewController
class SourceViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // 创建DestinationViewController实例
        let destinationVC = DestinationViewController()

        // 将闭包传递给DestinationViewController
        destinationVC.messageHandler = { message in
            print("Received message: \(message)")
        }

        // 显示DestinationViewController
        present(destinationVC, animated: true, completion: nil)
    }
}

这样,在DestinationViewController 中调用闭包时,会触发在SourceViewController 中定义的闭包处理函数,并将数据传递给它。在SourceViewController 中,您可以使用传递过来的数据进行后续的处理,例如打印出来。

使用通知传值

您可以使用通知中心在视图控制器之间传递数据。在源视图控制器中,您可以发布通知,并在目标视图控制器中使用通知中心接收该通知。

首先,在发送方视图控制器中,您可以在某个事件触发后,通过NotificationCenter发送一个自定义的通知,携带需要传递的数据。示例代码如下:

// 发送方视图控制器
// 发送自定义通知,并携带数据
let notificationData = ["message": "Hello, World!"]
NotificationCenter.default.post(name: Notification.Name("CustomNotification"), object: nil, userInfo: notificationData)

在接收方视图控制器中,您需要在视图加载时,注册对该通知的监听,以便在通知被发送时,能够接收并处理数据。示例代码如下:

// 接收方视图控制器
// 注册对自定义通知的监听
NotificationCenter.default.addObserver(self, selector: #selector(handleCustomNotification(_:)), name: Notification.Name("CustomNotification"), object: nil)

// 实现处理通知的方法
@objc func handleCustomNotification(_ notification: Notification) {
    if let data = notification.userInfo as? [String: Any], let message = data["message"] as? String {
        print("接收到的消息:\(message)")
    }
}

在接收方视图控制器中,需要在适当的时候,通过NotificationCenter.removeObserver()方法,取消对该通知的监听。这样可以避免出现重复监听的问题,同时也有助于释放内存。

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

Swift的几种传值方式 的相关文章

  • 指定访问组时出现 KeychainItemWrapper 错误

    相当长一段时间以来 我一直在使用 KeychainItemWrapper 的 ARC 版本成功读取和写入私有钥匙串项目 我现在正在努力将我的 iOS 应用程序转换为使用共享访问组 以便我的 2 个共享相同应用程序前缀的应用程序可以访问钥匙串
  • 在现有 iOS 应用程序中集成 React-native(0.40.0) 后找不到 Yoga/Yoga.h 头文件

    在我的 Swift iOS 应用程序中集成 React Native 后 我无法构建 yoga Yoga h file cannot be found 我已经浏览了文档 查看了react native github页面 检查了类似问题的SO
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件
  • 为什么我的视图仍然以横向呈现?

    我的视图是由导航控制器控制的 因此我将导航控制器支持的方向设置为明确的纵向和纵向UpSideDown 这可以工作 但是如果调用视图时前一个视图处于横向状态 它将以横向方式呈现并保持横向状态 直到设备旋转 如何防止这种情况发生 这是我的代码
  • 如何反转 CGPath 的点顺序

    我想画一个圆圈 并用它打出字母 为此 我需要顺时针抚摸圆圈 逆时针抚摸字母 这一切都很好 但是当我使用 Core Text 获取字母路径时 我不知道如何从本质上反转该路径 不是镜像或旋转或任何东西 这很简单 我希望点笔画顺序是逆时针的 这实
  • Xcode 存档上传失败并出现错误

    我正在尝试从 xCode 将新版本上传到 iTunesConnect 但每次我都会遇到此问题 问题是什么 我该如何解决这个问题 最近 我开始在上传过程中遇到问题 Xcode 经常卡住 最终会因您看到的第二个错误而失败 受够了一段时间后 我转
  • 在运行时获取 iPhone 应用程序的产品名称?

    如何才能实现这一目标 我想获取名称 以便可以在应用程序中显示它 当然 每次更改名称时不必在代码中更改它 Try this NSBundle bundle NSBundle mainBundle NSDictionary info bundl
  • IOS7 状态栏在选定控制器上隐藏/显示

    我想在某些控制器上显示和隐藏状态栏 这可以完成吗 或者它更像是一个整体应用程序设置 我看过很多关于 plist 更新的帖子 问题 View controller based status bar appearance NO 如果这完成了 那
  • 如果我的消耗性 IAP 被退款,我会收到任何通知吗?

    我有 Apple iOS 应用程序 其中有很多消耗性 IAP 我非常担心用户购买IAP并使用一段时间后向Apple客服投诉并获得退款 如果我的消耗品 IAP 退款 我会收到任何通知吗 我如何注意到这一点并阻止用户使用 IAP None
  • 在 iOS5 中使用 UISegmentedControl 切换 ViewController

    我正在尝试一些非常简单的事情 但不知何故我无法让它发挥作用 我尝试做的就是使用 UISegmentedControl 在 2 个视图控制器之间切换 就像您可以在 App Store 应用程序的 突出显示 选项卡中看到的那样 我正在使用 iO
  • Xcode 无法找到 strip-frameworks.sh 目录

    我最近将 Xcode 更新到版本 7 1 其中包括 Swift 2 1 我安装了 Swift 2 1 没有遇到任何问题 在尝试运行我的项目后 我意识到我需要获取最新版本的 Realm 因为之前的版本不支持 Swift 2 1 我删除了旧框架
  • 两者都实现了类。将使用两者之一

    我有一个项目 它具有使用 SocketRocket 的依赖项 通过 CocoaPods 安装 并从 HeapAnalytics 导入了静态库 显然 HeapAnalytics 库已经使用了 SocketRocket 编译时没有出现错误 但在
  • ViewWillAppear 没有被 UISplitViewController 调用

    背景和目标 我有一个基于 UISplitViewController 的 iPad 应用程序 到目前为止它支持 4 个方向 但现在我想将其锁定为仅横向 我变了shouldAutorotateToInterfaceOrientation左视图
  • 使用 NSURLSessionDataTask 显示文件下载进度

    我想显示特定文件的文件下载进度 收到了多少字节 它与 NSURLSessionDownloadTask 配合得很好 我的问题是我想用 NSURLSessionDataTask 实现同样的效果 以下是将文件接收到 NSData 并写入文档文件
  • 尝试复制文件时出错

    我正在尝试使用 NSFileManager 将临时文件复制到另一个位置 但是它失败并抱怨其中一个文件不存在 Copy temp file NSError error BOOL exists fileManager fileExistsAtP
  • -[EAGLContext renderbufferStorage:fromDrawable:] 第二次失败?

    我正在开发一个 iOS openGL ES 应用程序 我正在做通常的 EAGLView ES2Render 的事情 启动时 使用以下代码成功创建 frambuffer BOOL createFramebuffers EAGLContext
  • 将带有地理位置数据的照片保存到照片库 Swift 3

    如何使用地理位置元数据将照片保存到照片库 我已请求 并允许 应用程序访问用户位置 private func allowAccessToUserLocation locationManager CLLocationManager locati
  • 图像目录中矢量 pdf 的渲染模式设置为模板,但 UIImageView 不会在自定义单元格中对图像进行着色

    我已将所有图像文件迁移到资产目录中 它们都是大小为 1x 的 pdf 向量 它们被设置为呈现为模板 它们的大小和颜色在任何地方都表现得很好 但是有一个来自 xib 的自定义 TableView Cell 我有 6 个 UIImageView
  • GMSMapView 中的倒多边形

    我必须在我的 iPhone 项目中使用 Google 地图 并且我正在使用 GMSPolygon 来绘制多边形 但是如何填充地图上除多边形内部之外的所有位置 就像下图一样 谢谢 我玩过你的问题 主要思想是用多边形填充整个地球 然后为您的特定
  • 是什么导致了这个 iPhone 崩溃日志?

    我有点卡住了 需要解决这个问题 因为我的一个应用程序出现了随机崩溃 而这些崩溃并不总是能够重现 这是崩溃日志之一 Incident Identifier 59865612 9F00 44EA 9474 2BF607AD662E CrashR

随机推荐

  • WEB漏洞测试——HTML注入及XSS注入

    HTML注入 原理 目前我们所接触展示页面基本上都是由html来实现的 那么后台在处理内容的时候 是对html很少处理的 如果用户刻意通过输入框 文本框 查询框来填写html js代码 脚本注入 那么就会造成漏洞 若填写恶意网站 病毒网站
  • 基于Qt开发的游戏手柄小程序例子

    以前做过一个项目 用游戏手柄链接上位机软件 控制下位机执行一些机械动作 现在我将手柄控制的功能单独拿出来做了一个手柄检测的小程序 供开发者们拿去移植到自己的项目中用 这个程序是用 Qt creator5 12开发环境开发的 不过移植到VS
  • idea配置hibernate环境-零基础入门-详细版

    idea配置hibernate环境 下载hibernate所需jar包 官网链接 高速链接 用idea创建一个web项目 Create New Project gt 选择Java Enterprise gt 勾选Web Applicatio
  • 嵌入式毕设分享 STM32与wifi的天气预报网时钟系统

    文章目录 0 前言 1 设计内容 2 软件设计 3 关键代码 4 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉学长自己做的项目系统达不到老
  • 基于FPGA的正弦波发生器设计与实现

    基于FPGA的正弦波发生器设计与实现 摘要 本文介绍了一种基于FPGA的正弦波发生器的设计与实现 通过使用FPGA的数字信号处理功能 可以实现高精度 高性能的正弦波生成 文章首先介绍了DDS Direct Digital Synthesis
  • 《如何为Android Studio安装HAXM》

    Preface 1 Intel HAXM Hardware Accelerated Execution Manager 即英特尔硬件加速执行管理器 Intel HAXM 是一款硬件辅助虚拟引擎 管理程序 使用基于 Intel R Virtu
  • Python|excel表格数据一键转json格式小工具|支持xlsx、xls格式转json|【源码+解析】

    背景 最近在使用JavaScript编写一些浏览器RPA脚本 脚本使用过程中遇到一些问题 脚本使用的数据往往存放在excel表 但运行时只能读取json数据 导致频繁人工excel转json 效率低下 遇到问题后赶紧搜索excel转json
  • Selenium+Webdriver被检测识别出来的应对方案

    在写爬虫 面对很多js 加载的页面 很多人束手无策 更多的人喜欢用Senlenium Webdriver 古语有云 道高一尺魔高一丈 已淘宝为首 众多网站都针对 Selenium的js监测机制 比如 window navigator web
  • 转载:python 文件读写(追加、覆盖)

    with open file txt w as f f write content content 要放入文件的内容 要进行utf 8转码 可在pycharm中打开文件进行转码 x 创建一个新文件并打开它进行写入 b 二进制模式 t 文本模
  • 汇总下关于安全的13款必备工具

    汇总下关于安全的几款必备工具 1 burpsuite Burp Suite 是用于攻击web 应用程序的集成平台 http协议分析神器 里面包括了不少安全必备的功能 重放 爆破 扫描并且支持自定义脚本 实现自己想要的功能 Burp Suit
  • MacBook Big Sur 完美解决外接显示器 字体模糊、边缘不清 HIDPI 解决办法

    该文章转发MacBook Big Sur 完美解决外接显示器 字体模糊 边缘不清 HIDPI 解决办法 毕扬博客
  • error: invalid conversion from ‘void*‘ to ‘char*‘ [-fpermissive]

    include
  • 【计算机视觉】InvaSpread 讲解

    任何的书写错误 排版错误 概念错误等 希望大家包含指正 在阅读本篇之前建议先学习 机器学习 噪声对比估计 NCE 计算机视觉 MoCo 讲解 计算机视觉 InstDis 讲解 InvaSpread 在 InvaSpread 中 负样本的个数
  • 点云数据学习总结之一:点云数据存储格式

    最近研究点云数据 找了下相关的资料 看了许多的博文 下面总结了我认为比较写的比较好的博文链接 有需要的可以看下 刚刚才研究 所以可能不全 欢迎大家补充 共同学习 同时 未避免转载的博客链接失效 所以对博客内容进行了截图 如果原博主觉得受到侵
  • RestHighLevelClient封装使用,Java调用ES客户端 [支持ES6.x]

    前言 之前做项目的时候 需要用到Es的操作 本来想使用EsJpa的 即SpringDataElasticsearch 结果项目采用的是SpringBoot1 x版本 不得已 只要自己封装RestHighLevelClient来使用 不过网上
  • 蓝桥杯python技能升级

    只通过了百分之40 后面超时了 给没有头绪的伙计们一个思路吧 也请大佬给一个更好的解题思路 import math n m map int input split max 0 此为加的最大点 当加的次数小于0的时候 return0 if m
  • el-select下拉框只回显value不回显label的原因以及解决方法

    el select的采用的是map的key value结构 因此只显示value而不显示label的原因是 value的类型不正确 只需要在回显之前加上一行代码 将这个value转换成对应的类型即可 我这个里面需要的int类型 因此转成in
  • 集合相似度(PAT)

    题目链接 https www patest cn contests gplt L2 005 一开始用map超时了 总是有一组数据超时 当时觉得很纳闷 后来学到了 其实set也是可以开数组的 map也是 include
  • ubuntu 下安装chrome浏览器

    1 将google chrome stable current amd64软件复制移动到家目录下 2 打开终端 路径在家目录下 3 依次运行下面三条命令 sudo apt get install google chrome stable s
  • Swift的几种传值方式

    传值方式 在进行页面跳转过程中无法避免需要进行值的传递 那么值的传递可以分为正向传值和反向传值 例如在SourceViewController跳转至DestinationViewController的过程中需把前者的属性值传递给后者称为正向