You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift跨函数调用TextField:如何在@objc函数中访问viewDidLoad内的控件

解决Swift中跨函数访问控件的问题

嗨,作为Swift新手遇到这个问题太正常啦!你现在的核心问题是:subjectTextField、emailTextField和scrollTextView都是foo()函数里的局部变量——局部变量的作用域只限于它被声明的函数内部,所以在sendMail这个@objc方法里根本访问不到它们。

解决办法很直接,把这些控件从局部变量升级为你的ViewController类的实例属性,这样整个类的所有方法都能访问到它们。具体步骤如下:

步骤1:在ViewController类顶部声明属性

首先,找到你的ViewController类的定义,在类的开头(所有方法外面)声明这三个控件的属性:

class YourViewController: UIViewController, MFMailComposeViewControllerDelegate {
    // 声明为可选类型的实例属性,后续在foo()中初始化
    private var subjectTextField: UITextField!
    private var emailTextField: UITextField!
    private var scrollTextView: UITextView!
    
    // 你的其他类成员(比如viewDidLoad、foo()等)放在这里
}

注意:别忘了让你的ViewController遵守MFMailComposeViewControllerDelegate协议,不然邮件控制器的代理设置会报错。

步骤2:修改foo()函数中的控件初始化代码

把foo()里原来的let去掉,直接给刚才声明的类属性赋值:

func foo() { 
    //MARK: SubjectTextField 
    subjectTextField = UITextField(frame: CGRect(x: 50, y: 10, width: view2.frame.size.width - 100, height: 30)) 
    subjectTextField.placeholder = "Subject"
    subjectTextField.borderStyle = .none 
    subjectTextField.backgroundColor = .clear 
    subjectTextField.textColor = #colorLiteral(red: 0.2517931461, green: 0.2469081879, blue: 0.2469479442, alpha: 1) 
    subjectTextField.font = UIFont.init(name: "HelveticaNeue-Bold", size: 20) 
    subjectTextField.resignFirstResponder() 
    view2.addSubview(subjectTextField) 
    
    //MARK: Email Text Field 
    emailTextField = UITextField(frame: CGRect(x: 50, y: 40, width: view2.frame.size.width - 100, height: 30)) 
    emailTextField.placeholder = "Email"
    emailTextField.borderStyle = .none 
    emailTextField.backgroundColor = .clear 
    emailTextField.textColor = #colorLiteral(red: 0.2517931461, green: 0.2469081879, blue: 0.2469479442, alpha: 1) 
    emailTextField.font = UIFont.init(name: "HelveticaNeue-Thin", size: 16) 
    view2.addSubview(emailTextField) 
    
    //MARK: Scrollable Text View 
    scrollTextView = UITextView(frame: CGRect(x: 70, y: 70, width: view2.frame.size.width - 100, height: 100)) 
    scrollTextView.textColor = #colorLiteral(red: 0.4352585971, green: 0.4353140593, blue: 0.4352396429, alpha: 1) 
    scrollTextView.text = "Enter Your Message Here"
    scrollTextView.font = UIFont.init(name: "HelveticaNeue-Thin", size: 14) 
    view2.addSubview(scrollTextView) 
    
    //MARK: Create Mail Send Button 
    let sendMailButton = UIButton(frame: CGRect(x: 110, y: 600, width: view2.frame.size.width - 200, height: 50)) 
    sendMailButton.setTitle("SEND", for: .normal)
    sendMailButton.backgroundColor = .black 
    sendMailButton.setTitleColor(.white, for: .normal) 
    sendMailButton.titleLabel?.font = UIFont(name: "HelveticaNeue-Bold", size: 20) 
    sendMailButton.layer.cornerRadius = 5 
    sendMailButton.addTarget(self, action: #selector(sendMail), for: .touchUpInside) 
    mainScrollView.addSubview(sendMailButton) 
} 

步骤3:完善sendMail方法并添加代理方法

现在你可以在sendMail里正常访问这三个控件了,另外建议你做空值检查避免崩溃,还要实现邮件控制器的代理方法来关闭界面:

@objc func sendMail(_ button: UIButton) { 
    // 先检查输入内容是否为空,避免强制解包崩溃
    guard let subject = subjectTextField.text, !subject.isEmpty,
          let email = emailTextField.text, !email.isEmpty,
          let message = scrollTextView.text, !message.isEmpty else {
        // 这里可以加个提示,比如弹出alert告诉用户输入完整信息
        print("请填写完整内容")
        return
    }
    
    print("Works")
    let toDestination = ["contact@vaidusi.com"]
    let mc = MFMailComposeViewController() 
    mc.mailComposeDelegate = self 
    mc.setToRecipients(toDestination)
    mc.setSubject(subject) 
    mc.setMessageBody("Subject: \(subject) \n\nEmail:\(email) \n\nMessage: \(message)", isHTML: false) 
    self.present(mc, animated: true, completion: nil) 
}

// 实现邮件控制器的代理方法,关闭界面
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true, completion: nil)
}

这样修改后,点击按钮就能正常调用邮件控制器,并且获取到三个控件的内容啦!

内容的提问来源于stack exchange,提问作者Jimbob12505

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 20:18:13