YouTube Screenrecord of my workflow
FirstViewController
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let secondViewController = SecondViewController()
secondViewController.delegate = self
}
}
extension FirstViewController: DataEnteredDelegate {
func userDidEnterInformation(info: String) {
label.text = info
print("label changed")
}
}
SecondViewController
import UIKit
protocol DataEnteredDelegate: class {
func userDidEnterInformation(info: String)
}
class SecondViewController: UIViewController {
weak var delegate: DataEnteredDelegate? = nil
@IBOutlet weak var textField: UITextField!
@IBAction func sendTextBackButton(_ sender: UIButton) {
print("button tapped")
delegate?.userDidEnterInformation(info: textField.text!)
}
}
答案 0 :(得分:2)
除了缺少代表采用
class FirstViewController: UIViewController, DataEnteredDelegate {
如果视图控制器是在情节提要中设计的,则它不能工作。
行
let secondViewController = SecondViewController()
创建一个全新的SecondViewController
实例,它不是情节提要中的实例,不是,并且所有插座都未连接。
您必须使用segue或instantiate并出示第二个视图控制器才能获得对目标控制器的实际引用。
注意:
就Swift协议/委托而言,在控制器之间共享数据是 objective-c-ish 。
回调关闭更轻巧,更轻巧。
答案 1 :(得分:1)
您必须将第一个视图控制器更改为
main.R
原因是第一个视图控制器未实现协议,因此强制转换不会发生
答案 2 :(得分:1)
将协议实施到您的第一个视图控制器。好的做法是扩展控制器,然后将协议的委托方法用于此扩展
extension FirstViewController: DataEnteredDelegate {
func userDidEnterInformation(info: String) {
...
}
}
接下来,您要为其设置委托的第二个视图控制器可能不是您稍后要介绍的控制器。要正确设置委托,请设置将显示的控制器委托。如果您使用的是segues,请覆盖prepare(for:sender:)
并设置向下转换的segue目的地的委托。如果您是手动显示或按下视图控制器,请设置要显示/推动的该控制器的委托。
答案 3 :(得分:0)
检查并更新。
InputStream
答案 4 :(得分:0)
将以下代码用于FirstView Controller
import UIKit
class FirstViewController: UIViewController, DataEnteredDelegate {
@IBOutlet weak var label: UILabel!
func userDidEnterInformation(info: String) {
label.text = info
}
override func viewDidLoad() {
super.viewDidLoad()
let secondViewController = SecondViewController()
secondViewController.delegate = self
}
func userDidEnterInformation(info: String){
// do your stuff here
}
}
答案 5 :(得分:0)
我相信您正在面临此问题,因为您将委托设置为nil。
尝试这样设置:
weak var delegate: DataEnteredDelegate? = FirstViewController.self as! DataEnteredDelegate
答案 6 :(得分:0)
在这里,SecondViewController的直接初始化是不可接受的。此外,经过两个步骤,第二个ViewController将被释放并且不存在。
override func viewDidLoad() {
super.viewDidLoad()
let secondViewController = SecondViewController() // Not the right way to initialize!
secondViewController.delegate = self. //secondViewController will be released!
}
答案 7 :(得分:0)
问题是,您正在创建一个新的SecondViewController
,而不是标签栏实际使用的UITabBarController
。您需要访问viewDidLoad
所使用的第二个视图控制器,而不是分配新的实例,为此,将override func viewDidLoad() {
super.viewDidLoad()
let secondViewController = self.tabBarController?.viewControllers?.last as? SecondViewController
secondViewController.delegate = self
}
的实现更改为:
@Override
public void getUsersForTwentyMiles() {
FirebaseFirestore db = FirebaseFirestore.getInstance();
double latitude = 33.0076665;
double longitude = 35.1011336;
int distance = 20; //20 milles
GeoPoint lg = new GeoPoint(latitude, longitude);
// ~1 mile of lat and lon in degrees
double lat = 0.0144927536231884;
double lon = 0.0181818181818182;
final double lowerLat = latitude - (lat * distance);
final double lowerLon = longitude - (lon * distance);
double greaterLat = latitude + (lat * distance);
final double greaterLon = longitude + (lon * distance);
final GeoPoint lesserGeopoint = new GeoPoint(lowerLat, lowerLon);
final GeoPoint greaterGeopoint = new GeoPoint(greaterLat, greaterLon);
Log.d(LOG_TAG, "local general lovation " + lg);
Log.d(LOG_TAG, "local lesserGeopoint " + lesserGeopoint);
Log.d(LOG_TAG, "local greaterGeopoint " + greaterGeopoint);
//get users for twenty miles by only a latitude
db.collection("users")
.whereGreaterThan("location", lesserGeopoint)
.whereLessThan("location", greaterGeopoint)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
UserData user = document.toObject(UserData.class);
//here a longitude condition (myLocation - 20 <= myLocation <= myLocation +20)
if (lowerLon <= user.getUserGeoPoint().getLongitude() && user.getUserGeoPoint().getLongitude() <= greaterLon) {
Log.d(LOG_TAG, "location: " + document.getId());
}
}
} else {
Log.d(LOG_TAG, "Error getting documents: ", task.getException());
}
}
});
}
答案 8 :(得分:0)
您的UIWndow的rootViewController是UITabBarController,您共享的YouTube视频链接上可以看到它UITabBarController,因此您需要使用此代码段从该位置获取SecoundViewController
class FirstViewController: UIViewController {
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let rootController = appDelegate.window?.rootViewController as! UITabBarController
if let viewControllers = rootController.viewControllers {
if viewControllers.count > 0 {
if let secondViewController = viewControllers[1] as? SecondViewController {
secondViewController.delegate = self
}
}
}
}}
这样您的代表将不会为零。
在当前解决方案中,您的SecondViewController
获得了新实例,但未从情节提要中加载,并且委托中没有nil,因此委托方法无法调用。
// you have nil refrence to delegate check it here
if (self.delegate != nil) {
self.delegate?.userDidEnterInformation(info: textField.text ?? "")
}
希望有帮助。