My view contain a button which bring a custom view which contain a ContainerView and it has a label. When I bring the custom view to the front I get the label text empty. So please where would be my issue?
View Controller Code:
#IBAction func PushAlert(sender: UIButton) {
let alert = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("alertViewController") as! AlertViewController
var alertText = AlertTextViewController()
alertText.lblText = "DONE"
alert.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
alert.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
self.presentViewController(alert, animated: true, completion: nil)
}
class AlertTextViewController: UIViewController {
#IBOutlet weak var lblAlertText: UILabel!
var lblText = ""
override func viewDidLoad() {
super.viewDidLoad()
lblAlertText.text = lblText
}
}
I have created a link for the source code which will be much easier to understand source code
What about var lblText: String? in your AlertTextViewController.
Maybe it's overriden by your declaration (for some reason I wouldn't be able to explain)?
Or wait, I'm confused by
var alertText = AlertTextViewController()
as you are presenting creating and presenting the ViewController alert. How is alertText and alert related?
Edit:
class AlertViewController: UIViewController {
#IBOutlet weak var container: UIView!
override func viewDidLoad() {
super.viewDidLoad()
var alertText: AlertTextViewController = self.childViewControllers[0] as! AlertTextViewController
alertText.lblAlertText.text = "Test"
// Do any additional setup after loading the view.
}
Do this in your AlertViewController, and it works. I don't know what your final purpose is though, and this might not be the most elegant solution. I've created an outlet, the containerView to your class.
I think you may have a order of events problem. Try setting lblAlertText.text in viewWillAppear instead of viewDidLoad.
Related
I have a share button. When the share button is tapped, the view controller runs code like this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet weak var popOverView: UIView!
#IBOutlet weak var shareButton: UIButton!
#IBAction func share()
{
let text = "Sharing."
if let url = URL(string: "https://www.apple.com")
{
let items = [text,url] as [Any]
let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
if let popoverViewController = activityViewController.popoverPresentationController
{
popoverViewController.sourceView = popOverView
// popoverViewController.sourceRect = popOverView.frame
}
present(activityViewController, animated: true, completion: nil)
print(activityViewController.popoverPresentationController?.sourceView)
}
}
}
This works, but produces this:
when I want something like this, because the content to be shared won't be on this view controller:
How do I get the screen that I want?
I think you need to do this:
sharingViewController.modalPresentationStyle = .popover
before you set the sharingViewController.popoverPresentationController?.sourceView property. sharingViewController.popoverPresentationController is nil until you do this.
Unfortunately that is not possible on iPad.
Sorry for the bad news!
If you truly, truly wanted that look, you'd have to make a completely custom view controller that sits down there (ie, no connection to UIActivityViewController), of course that would be an unrealistic amount of work.
This is in the latest XCode, 11.3. I've looked through the answers to similar questions, but some of the function names and parameters seem to have changed.
While working through a Udemy course, I'm trying to make a simple log in / sign up interface. In my first view controller I have a vertical stack view containing a label, a segmented control, and a container view. The segmented control can be either "Log In" or "Sign Up". I want to load the appropriate view controller when the segmented control changes.
My LogInViewController has a vertical stack view with a text field for username, another for password, and a Log In button. My SignUpViewController has a vertical stack view with text fields for email address, username, password, and password confirmation followed by a Sign Up button.
My first view controller looks like this:
class ViewController: UIViewController
{
#IBOutlet weak var logInSignUpControl: UISegmentedControl!
#IBOutlet var customContainer: UIView!
var logInVC: LogInViewController?
var signUpVC: SignUpViewController?
var activeVC = 0
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view.
initializeCustomControllers()
}
func initializeCustomControllers()
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
logInVC = storyboard.instantiateViewController(withIdentifier: "LogInViewController") as? LogInViewController
signUpVC = storyboard.instantiateViewController(withIdentifier: "SignUpViewController") as? SignUpViewController
logInVC?.willMove(toParent: self)
logInVC?.view.frame = customContainer.bounds
customContainer.addSubview(logInVC!.view)
addChild(logInVC!)
logInVC?.didMove(toParent: self)
}
Unfortunately, this only shows the LogInViewController, not the label or segmented control.
I haven't been able to find a clear description of how to do this in the latest version of XCode and Swift, so I've pieced this together from various blog posts and Stackoverflow comments about older versions. Any help is greatly appreciated.
Try the below code :)
PS: #IBAction func controlChanged(_ sender: Any) is an IBAction for the "ValueChanged" Event
class ViewController: UIViewController {
#IBOutlet weak var logInSignUpControl: UISegmentedControl!
#IBOutlet var customContainer: UIView!
var logInVC: LogInViewController?
var signUpVC: SignUpViewController?
var activeVC = 0
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view.
initializeCustomControllers()
}
#IBAction func controlChanged(_ sender: Any) {
changeVC()
}
func changeVC() {
if activeVC == 0 {
signUpVC?.view.removeFromSuperview()
logInVC?.willMove(toParent: self)
logInVC?.view.frame = customContainer.bounds
customContainer.addSubview(logInVC!.view)
addChild(logInVC!)
logInVC?.didMove(toParent: self)
} else {
logInVC?.view.removeFromSuperview()
signUpVC?.willMove(toParent: self)
signUpVC?.view.frame = customContainer.bounds
customContainer.addSubview(signUpVC!.view)
addChild(signUpVC!)
signUpVC?.didMove(toParent: self)
}
activeVC = activeVC == 0 ? 1 : 0
}
func initializeCustomControllers()
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
logInVC = storyboard.instantiateViewController(withIdentifier: "LogInViewController") as? LogInViewController
signUpVC = storyboard.instantiateViewController(withIdentifier: "SignUpViewController") as? SignUpViewController
changeVC()
}
}
Make sure this #IBOutlet var customContainer: UIView! is linked to the containerview and not to the vc's main view in storyboard
class FourthViewController : UIViewController {
#IBOutlet weak var previousLabel: UILabel!
#IBOutlet weak var backButton: UIButton!
var delegate: FourthToFirst?
var label = ""
// MARK: - Lifecycle method
override func viewDidLoad() {
super.viewDidLoad()
previousLabel.text = label
let fourthViewController = storyboard?.instantiateViewController(withIdentifier: "FourthViewController") as? FourthViewController
navigationController?.pushViewController(fourthViewController!, animated: true)
}
// MARK: - IBAction
#IBAction func backToFirst(_ sender: Any) {
navigationController?.popToRootViewController(animated: true)
}
Actually I am in fourthviewController it was going recursively(i.e pushing the fourthViewcontroller again and again, nonstop)
if I pressed back button in the controller I have to go back(i.e firstviewcontroller)
problem is:
In my code it was going (i.e non stop)
I can't press the back button to go back(i.e firstviewcontroller)
navigationController?.popViewController(animated: true) instead of navigationController?.popToRootViewController(animated: true) could be what's you need mate. (Based on what's you just edited)
I have an UI where the SCNView is in the background, and a WKWebView is in the foreground presented as a .popover. Views are controlled by separate view controllers. The WKWebView appears when user presses the bell button (see the attached screen). SCNView has standard camera control enabled.
Currently when the WKWebView popover appears the SCNView becomes unresponsive. Tap gesture outside the WKWebView closes it, other gestures are ignored, so user cannot control SCNView camera while WKWebView popover is visible. How can I make the SCNView responsive while WKWebVIew popover is present? How can I dismiss the WKWebView only when the bell button is pressed?
Code used below:
class MainVC: UIViewController, UIPopoverPresentationControllerDelegate {
#IBOutlet weak var scnView: SCNView!
#IBOutlet weak var bellBtn: UIButton!
var myWebViewVC: MyWebViewVC!
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene(named: "art.scnassets/DemoScene.scn")!
let scnView = sceneView
scnView!.scene = scene
scnView!.allowsCameraControl = true
}
#IBAction func onBellBtnPressed(_ sender: UIButton) {
myWebViewVC.modalPresentationStyle = .popover
myWebViewVC.popoverPresentationController?.delegate = self
present(myWebViewVC, animated: true, completion: nil)
myWebViewVC.popoverPresentationController?.sourceView = sender
myWebViewVC.popoverPresentationController?.sourceRect = sender.bounds
}
}
The MyWebViewVC takes care only of the size of the view. No additional custom modifications are implemented in the file.
Ok. So the solution is mainly connected with the popoverPresentationController parameter of the view controller. Here is documentation. To enable control on the view beneath the view presented as a .popover you need to inform it about the views which are going to be responsive when popover is present. The order of the passing is top to bottom. The code below and the passThrough array make it work.
class MainVC: UIViewController, UIPopoverPresentationControllerDelegate {
#IBOutlet weak var scnView: SCNView!
#IBOutlet weak var bellBtn: UIButton!
#IBOutlet weak var dotBtn: UIButton!
var myWebViewVC: MyWebViewVC!
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene(named: "art.scnassets/DemoScene.scn")!
scnView!.scene = scene
scnView!.allowsCameraControl = true
}
#IBAction func onBellBtnPressed(_ sender: UIButton) {
activeUiNavigationUnderPopover()
}
func activeUiNavigationUnderPopover () {
myWebViewVC.modalPresentationStyle = .popover
myWebViewVC.popoverPresentationController?.delegate = self
if let pop = myWebViewVC.popoverPresentationController {
var passthroughViews: [AnyObject]?
passthroughViews = [dotBtn, scnView]
pop.passthroughViews = NSMutableArray(array: passthroughViews!) as? [UIView]
pop.permittedArrowDirections = .any
pop.delegate = self
}
present(myWebViewVC, animated: true, completion: nil)
myWebViewVC.popoverPresentationController?.sourceView = sender
myWebViewVC.popoverPresentationController?.sourceRect = sender.bounds
}
}
I am trying to pass information to my custom PopUpViewController using the github extension (https://github.com/Orderella/PopupDialog). The Popup uses a viewcontroller I've named PopUpViewController(with a xib file), and the view controller that the PopUp is initiated from is called MainViewController.
The information passed to the PopUpViewController will be an array(named: popUpArray) of type String and used for displaying the contained information within a table (named: tableView).
MainViewController code:
func showCustomDialog(_ sender: UIButton) {
// Create a custom view controller
let PopUpVC = PopUpViewController(nibName: "PopUpViewController", bundle: nil)
// Create the dialog
let popup = PopupDialog(viewController: PopUpVC, buttonAlignment: .horizontal, transitionStyle: .bounceDown, gestureDismissal: true)
// Create second button
let buttonOne = DefaultButton(title: "Ok", dismissOnTap: true) {
}
// Add buttons to dialog
popup.addButton(buttonOne)
// Present dialog
present(popup, animated: true, completion: nil)
}
PopUpViewController Code:
import UIKit
class PopUpViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
Just declare a new variable on PopUpViewController called data with type Array<String>.
After this, when you are creating your viewController, you can just pass it to the controller. After that it is just a simple tableView implementation in PopUpViewController to display the data.
Extend PopUpViewController with data parameter.
import UIKit
class PopUpViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
// Data variable
public var data: [String] = []
}
Add the data upon calling showCustomDialog() function
// Create a custom view controller
let PopUpVC = PopUpViewController(nibName: "PopUpViewController", bundle: nil)
// Assign the data
PopUpVC.data = popUpArray
Create a convenience init in PopUpViewController like following
convenience init(nibName: String, arrayOfString: [String] ){
self.data = arrayOfString
self.init(nibName: nibName, bundle:nil)
}
Then on MainViewController call the convenience init you just created like this something like this
// Create a custom view controller
let PopUpVC = PopUpViewController("PopUpViewController", arrayOfString: ["String1", "String2"])