How to find out the position of the contentViews inside tableView cell? - swift3

I placed a view inside a TableView Cell and have divided that view into 7 parts. Also, each view is assigned with a tag. Now, whenever I select a view, I want to find out the tag for identification and all I am getting is indexPath of the cell and details of all the views in it.
How can I find out the exact location or tag of the selected view? Don't want to use gesture. Can anyone help me out with this.
Thanks in advance.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var cell = tableView?.cellForRow(at: indexPath)
print(cell?.contentView.subviews)
}

What tag is that, you could get your cell properties normally after you got the cell.
if let cell = tableView?.cellForRow(at: indexPath) as? YourCellClass {
tag = cell.tag
}
print(cell?.contentView.subviews)

Related

UIHostingViewController background color showing

I am showing a UIViewController via a SwiftUI view, like so:
#available(iOS 13, *)
struct WelcomeNavView: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<WelcomeNavView>) -> UINavigationController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navVc = storyboard.instantiateViewController(withIdentifier: "welcomeNav") as! UINavigationController
return navVc
}
func updateUIViewController(_ uiViewController: UINavigationController, context: UIViewControllerRepresentableContext<WelcomeNavView>) {
}
}
I then present it from a ViewController like so:
self.viewController?.present(style: .fullScreen) {
WelcomeNavView()
}
However, it does not occupy the entire screen and the UIHostViewController color is showing at the top and bottom:
How can I change the color of the UIHostingViewController's view.. Or expand the View it is holding to occupy the entire screen?
Another simple and quick solution is, you can ignore safe area of your WelcomeNavView() while presenting.
example
iOS 13:
WelcomeNavView().edgesIgnoringSafeArea(.all)
iOS 14 and above:
WelcomeNavView().ignoresSafeArea()
Here is the solution,
I ran into similar problem, wherein I had to set hosting view controller's background clear.
Apparently, rootView (probably our SwiftUI View) of hostingVC and hostingVC.view are different.
so this would allow you to change to background color.
hostingVC.view.backgroundColor = .clear
Of course use any color in place of ".clear".
Just keep in mind to change color of SwiftUI view passed as rootView to hostingVC accordingly, mostly make that clear, so it won't be shown against above set color.
Your_SwiftUI_View.background(Color.clear)

Pass variable to next View Controller

I want to pass a variable from one view controller to another.
First View Controller looks like this and the segue gets triggered correctly and the new view controller gets displayed.
#IBAction func testButton(_ sender: Any) {
let timerVC = TimerViewController()
timerVC.secondsPassed = textfield_seconds.text!
navigationController?.pushViewController(timerVC, animated: true)
}
On the next View Controller (TimerViewController) I declared a variable in the class header
var secondsPassed:String!
and in viewDidLoad I just want to print the value to the console and all I receive is a 'nil'.
I looked through various tutorials but I seem not to find the correct answer for this to get it work.
Anyone around with a clue?
Thanks in advance...
If you already are using a segue, you can remove this line that presents the controller (you don't seem to have a navigationController anyway):
navigationController?.pushViewController(timerVC, animated: true)
Now the correct way to pass data to another VC using segues is this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? TimerViewController {
vc.secondsPassed = textfield_seconds.text!
}
}

How to change the way in which the root controller of a navigation controller is appearing on screen?

The navigation controller is not the initial view controller. It is being instantiated in the initial VC and supplied with a root controller, the second VC. When I call present view controller function I cannot change the way in which this new VC in being presented, it always appears from the bottom. I did not find how to make it come from right to left. I tried to change who gets the call to modalPresentaionStyle from the second VC to the nav con and back but no change.
Code listing below. Thank you for your help.
#objc fileprivate func showRegisterScreen() {
let registerAccountVC = RegisterAccountVC()
let navigationController = UINavigationController(rootViewController: registerAccountVC)
navigationController.modalPresentationStyle = .pageSheet
present(navigationController, animated: true, completion: nil)
}
This will add a custom animation from right to left.
let transition = CATransition.init()
transition.duration = 0.4
transition.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromRight
view.window?.layer.add(transition, forKey: nil)
present(navigationController, animated: false, completion: nil)

Automatic presenting View Controller

I have 2 view controllers on my storyboard: viewController1(it input point) and viewController2. After loading the application i want to automatic presenting viewController2 after viewController1.
How i can do that?
if you want to go to second viewcontroller you can add this code to you viewDidLoad method:
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "yourIdentifier") as! secondViewController
self.navigationController?.pushViewController(secondViewController, animated: true)
remeber to add a identifier for the second viewcontroller in storyboard and chenge the identifier that you use with "yourIdentifier"
if you don't want a animation put the animated: true to false.
if you dont want to show the fist viewcontroller, go into you storyboard and click on the second viewcontroller, then in the right side on attributes inspector select the box int the image:
For change viewcontroller you have to embed the first viewcontroller with a navigation controller, if you don't know how to do it, just select the fisrt viewcontroller and do like the image, click in navigation controller
Have you tried to show it in func viewDidLoad() {} like:
override func viewDidLoad() {
// ...
self.present(viewController, animated: true, completion: nil)
}
If you want to straight up load a different view controller you can do this in your app delegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "put your identifier here")
self.window?.rootViewController = vc
return true
}

Data not passing from main VC to embedded VC via prepareForSegue

I am trying to pass data from the main VC (called StartVC) to an embedded VC (called MPList - which itself contains a tableview).
The solutions I have found all point to using the prepareforsegue method but this does not seem to work for me. The app runs with no errors and the tableview is not getting populated with the data I send.
In StartVC, I have implemented the prepareforsegue method as follows (In the attributes inspector, the embed segue definitely has an identifier of "LeftPane".):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "LeftPane"{
let mpListVC = segue.destination as? MPList
mpListVC?.mpNames = self.mpNames
}
}
mpNames is a string array initialised in the embedded MPList as follows (mpListTV is the IBOUTLET for the tableview in question):
class MPList: UIViewController, UITableViewDataSource, UITableViewDelegate{
var mpNames = [String]()
override func viewDidLoad() {
super.viewDidLoad()
mpListTV.delegate = self
mpListTV.dataSource = self
print("names in MPList is: \(mpNames)")
}
The usual tableview control methods are implemented in MPList as well (and this is where mpNames is used too.):
//MARK: - TABLEVIEW METHODS
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return mpNames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = mpNames[indexPath.row]
return cell
}
I have also made sure to right click and drag from the tableview to the little yellow icon at the top of the MPList viewcontroller and set both datasource and delegate.
I might just be tired (and missing something really obvious) after being at this for several hours now, but could someone please put me out of my misery and tell me what I am getting wrong?
Possible problems I see here:
1.
//in prepareForSegue
let mpListVC = segue.destination as? MPList
Make sure that the destination view controller in the IB is indeed set to MPList. Maybe mpListVC is nil here because of that. Just debug and make sure that mpListVc is not nil.
Also debug and make sure that no optional is nil. Better yet use force unwrapping (!) to try and find a possible nil somewhere.
Just set a breakpoint and check if mpNames is indeed set.
2.
viewDidLoad of MPList might be called before prepareForSegue for some reason, although it shouldn't. Either way it's a good practice to reloadData of the UITableView after resetting the array.
var mpNames = [String]() {
didSet {
mpListView?.reloadData()
}
}