Screen transition cannot be done - ios

I wanna transition screens in my app but it cannot be done.
I used TabBarController and I made Tab1 item and Tab2 item.
When I tapped Tab2 in my simulator, my app dropped.
import UIKit
import SwiftyJSON
class ViewController: UIViewController {
#IBOutlet var KenshinPic: UITabBarItem!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController : UITabBarControllerDelegate {
public func tabBarController(tabBarController: UITabBarController, viewController: UIViewController) -> Bool {
if(viewController.restorationIdentifier == "first") {
self.tabBarController!.setViewControllers([KenshinSendController() , KenshinViewController()], animated: false);
let items = self.tabBarController!.tabBar.items;
items![1].title = "Second";
items![0].title = "First";
return false;
}
return true;
}
}
Below sentences didn't be called in Xcode when I run my app.
enter code here
self.tabBarController!.setViewControllers([KenshinSendController() , KenshinViewController()], animated: false);
Error message was 'signal SIGABRT'
in class AppDelegate: UIResponder, UIApplicationDelegate {
of AppDelegate file.
What shoud I do?

Related

prepare for segue not being called with tabbarcontroller

Im using Xcode 8 and swift 3
I created a new project selecting new "Tabbed Application" when i created it. It provided two UIViewControllers embedded in one tab bar controller. I'm trying to pass two variables between the view controllers.
The problem is that the prepare for segue function is never called. I added a print statement in it that never prints. I added the prepare function in both view controllers and can tab back and forth with no prints.
Some code:
import UIKit
import MapKit
import CoreLocation
class FirstViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate{
#IBOutlet weak var mapView: MKMapView!
var locationManager:CLLocationManager?
var currentLocation:CLLocation?
var destPin: MapPin?
var isTracking: Bool? = false
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.startUpdatingLocation()
locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager?.requestAlwaysAuthorization()
updateTracking()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.currentLocation = locations[0]
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func getMapView()-> MKMapView{
return mapView
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if(self.isTracking!){
print("Istracking bool is true")
}
else{
print("Istracking bool is false")
}
updateTracking()
locationManager?.stopUpdatingLocation()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("Preparing")
let barViewControllers = segue.destination as! UITabBarController
let destinationViewController = barViewControllers.viewControllers![1] as! FirstViewController
destinationViewController.destPin = self.destPin
destinationViewController.isTracking = self.isTracking
}
}
The contents of the prepare function may very well be wrong as well but without the function even being called it hardly matters. The other view controller is also embedded in the tab bar controller and also has a prepare function that does not execute.
If you'd like, its in this github repo
It is easy to do:
The result:
For example, there are FirstViewController and SecondViewController embeded in tabViewController:
In your firstViewController.swift:
import UIKit
class FirstViewController: UIViewController {
var vc1_variable:String = "first vc's variable."
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In your secondViewController.swift:
import UIKit
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let first_vc:FirstViewController = self.tabBarController?.viewControllers![0] as! FirstViewController
print("\(first_vc.vc1_variable)")
}
}

Looking understand why delegate keep alive

I have the following structure
Main ViewController: it is responsible to call the (A) view controller.
(A) ViewController: create an CustomClass instance and has a delegate for this class.
CustomClass: in each period of 1 second, a message is sent to (A) view controller via delegate.
Until here all works fine. Once I returned to Main ViewController the delegate keep alive, in other words, the delegate updates A(ViewController) variable. I checked that viewDidDisappear of (A) ViewController is called.
When I return again from Main ViewController to (A) ViewController, a new variable instance is created. I don't understand this anyway.
Besides this doubt, I would like to understand why the delegate keep alive when I return to main view controller. I am using a UINavigationItem to navigation.
I am a beginner in IOS development.
Thanks advanced!!!
Edit 1:
The (A)ViewController is called from MainViewController by Segue. The segue was added via storyboard.
MainViewController.swift
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
AViewController.swift
class ScanDevices : UIViewController, CustomClassDelegate {
var myInts : [Int] = []
var customClass : CustomClass!
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad")
if customClass == nil {
customClass = CustomClass()
customClass.customClassDelegate = self
}
}
override func viewWillAppear(animated: Bool) {
print("viewWillAppear")
}
override func viewDidAppear(animated: Bool) {
print("viewDidAppear")
}
override func viewWillDisappear(animated: Bool) {
print("viewWillDisappear")
}
override func viewDidDisappear(animated: Bool) {
print("viewDidDisappear")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func didDiscoverPeripheralInt(peripheral: Int) {
myInts.append(peripheral)
print("Number = \(myInts.count)")
}
}
CustomClass.swift
class CustomClass : NSObject {
var customClassDelegate : CustomClassDelegate?
// MARK: init
override init() {
super.init()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "writeInt", userInfo: nil, repeats: true)
}
func writeInt () {
CustomClassDelegate?.didDiscoverPeripheralInt(3)
}
}
var customClassDelegate : CustomClassDelegate?
You are holding a string reference to your delegate.
It needs to be
weak var customClassDelegate : CustomClassDelegate?
Take a look at the following document :
http://krakendev.io/blog/weak-and-unowned-references-in-swift
Your CustomClass holds strong reference to the delegate. You have to mark the property with weak:
weak var customClassDelegate : CustomClassDelegate?

Text from TextBox to Widget?

So i am making an iOS app, that lets you to enter text into a TextBox and then there is a Button that will display the "Text" on a label, and that "Text" on the label will be Displayed in the Notification Center, on a widget, But something is going wrong Because every time i run the app it fails and throws me into the AppDelegate.Swift and highlights me this specific part: "class AppDelegate: UIResponder, UIApplicationDelegate {"
with an error that says "Thread 1: signal SIGABRT"
i Don't know what else to do ;( please help!!
This is the ViewController.Swift code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var UserInput: UITextField!
#IBOutlet var TextDisplay: UILabel!
#IBAction func DisplayButton(sender: AnyObject) {
let Text:String = UserInput.text!
if let Text = Int(Text) {
print("Computer says no!")
} else {
TextDisplay.text = (Text)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let SharedDefaults = NSUserDefaults(suiteName: "group.St33v3n.TextOnWidget")
SharedDefaults?.setObject(UserInput, forKey: "StringKey")
SharedDefaults?.synchronize()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
and Here is the TodayView controller code (the one from the widget):
import UIKit
import NotificationCenter
class TodayViewController: UIViewController, NCWidgetProviding {
#IBOutlet var TextToWidget: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view from its nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) {
let ShareDefaults = NSUserDefaults(suiteName:"group.St33v3n.TextOnWidget")
self.TextToWidget.text = ShareDefaults?.objectForKey("StringKey") as? String
completionHandler(NCUpdateResult.NewData)
}
}
In the line
SharedDefaults?.setObject(UserInput, forKey: "StringKey")
you are passing UITextField object, not the text. You should use
SharedDefaults?.setObject(UserInput.text, forKey: "StringKey")
I'm not sure if that is causing the crash, but it needs correction anyway ;)

My Protocol is not Calling

I am using protocol for call method but my method does not call.Is there is any example which i use.
Here is my code:
ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
extension ViewController :ViewController1Delegate
{
func hello()
{
println("hbgyguyg");
}
}
In View Controller 1
import UIKit
#objc
protocol ViewController1Delegate
{
optional func hello()
}
class ViewController1: UIViewController {
var delegate: ViewController?
override func viewDidLoad() {
super.viewDidLoad()
delegate?.hello()
}
}
Please Help, I am new in Swift.Any help would be apperciated. Thanks in Advance
An example demo.
ViewController file
import UIKit
class ViewController: UIViewController, PopUpViewControllerDelegate
{
var popupVC: PopUpViewController!;
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view!.backgroundColor = UIColor.whiteColor();
self.popupVC = PopUpViewController();
self.popupVC.delegate = self;
self.showPopUpVC();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func popUpViewControllerDidPressOK(popUpVC: PopUpViewController) {
println("Yay?");
self.closePopUpVC();
}
func showPopUpVC()
{
let delayTime = dispatch_time(DISPATCH_TIME_NOW,
Int64(1.0 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
self .presentViewController(self.popupVC, animated: true, completion: nil);
}
}
func closePopUpVC()
{
let delayTime = dispatch_time(DISPATCH_TIME_NOW,
Int64(1.0 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
self.dismissViewControllerAnimated(true, completion: nil);
}
}
}
PopUpViewController file
import UIKit
protocol PopUpViewControllerDelegate
{
func popUpViewControllerDidPressOK(popUpVC: PopUpViewController);
}
class PopUpViewController: UIViewController {
var delegate: PopUpViewControllerDelegate!;
override func viewDidLoad() {
super.viewDidLoad()
self.view!.backgroundColor = UIColor.redColor();
// Do any additional setup after loading the view.
self.delegate!.popUpViewControllerDidPressOK(self);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Notice how in my ViewController viewDidLoad() method, I have a line that initialises the popUp view controller and then set its delegate to be the ViewController itself:
self.popupVC = PopUpViewController();
self.popupVC.delegate = self; // you're missing this line I believe ?
I don't use Interface Builder or Storyboard but maybe select your VC1 in your Storyboard and look in the connections inspector to see if you drag a line from "delegate" to your ViewController file owner thing.
In the end, you should see a red screen popup after 1 second, followed by the word "Yay?" logged into your Xcode console and finally the popupVC dismisses.

Delegate Not Called In SWIFT iOS

I am Created 2 Views, One is and Used Protocol and Delegate. For first view the Delegate function is not called.
My FirstView Controller : Here I am Accessing the Delegate Function.
import UIKit
class NextViewController: UIViewController,DurationSelectDelegate {
//var secondController: DurationDel?
var secondController: DurationDel = DurationDel()
#IBAction func Next(sender : AnyObject)
{
let nextViewController = DurationDel(nibName: "DurationDel", bundle: nil)
self.navigationController.pushViewController(nextViewController, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
secondController.delegate=self
}
func DurationSelected() {
println("SUCCESS")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
My SecondView Controller : Here I Am creating Delegate.
import UIKit
protocol DurationSelectDelegate {
func DurationSelected()
}
class DurationDel: UIViewController {
var delegate: DurationSelectDelegate?
#IBAction func Previous(sender : AnyObject) {
//let game = DurationSelectDelegate()
delegate?.DurationSelected()
self.navigationController.popViewControllerAnimated(true)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
To me, it looks like you're pushing a view controller that you haven't actually set the delegate for. If you change your "Next" function, to include the line
nextViewController.delegate = self
You should see that the delegation works. In doing this, you can also probably remove the creation of "secondController", as it looks like that's redundant.
The naming convention you have followed would confuse fellow developers in your team. The instance should have been
let durationDel = DurationDel(nibName: "DurationDel", bundle: nil)
And then as #Eagerod mentioned, the delegate you would set is
durationDel.delegate = self

Resources