I have a static table view with UITableViewController. I add UIImageView to first cell and connect this UIImageView outlet to my custom UITableViewController.
Inside viewWillAppear after super.viewWillAppear(animated) I try to set image for image view, but it looks hidden. Only if I do this inside viewDidAppear my image is shown. I have no implemented methods from UITableViewDelegate/DataSource and my image view is always not hidden. If I call reloadData() nothing happens (it's useless for static tables).
I want my image set before viewDidAppear, so I don't want to see delay before my image is set.
class FPProfileViewController: UITableViewController {
#IBOutlet weak var userPhotoImageView: UIImageView!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
userPhotoImageView.image = //myImage
}
}
It looks strange, in my other project the same algorithm works fine.
I think this is what you're looking for, had the same problem. It seems UIImageView's in a static table view cell need to be part of - (void) viewWillAppear - based on this answer : Static cells: Content does not appear.
For my situation, it didn't help, I had to go straight in - (void) viewDidLoad.
Related
I am neither an iOS developer, nor a swift developer, but please bear with me:
I am currently trying to implement a simple iOS app but I have difficulties understanding how exactly I am supposed to set up custom UIViews and ViewControllers for those UIViews.
I am using a UIScrollView that is containing items a little bit more complex than just images, thats what I use custom views for.
What I did was:
I created a .xib file, the view itself. I added some elements (here it is only a textfield, for simplicity's sake).
I created a cocoa touch class "CustomView" that inherits from UIView and set my view up to be of that class (inside the class I just set up elements and such).
Now I want a ViewController that controls the class whenever it is rendered (for example reacting to the changing textField).
I cant manage everything from my main ViewController, because it would get too big (e.g. 3 scrollViews * 5 subviews that need to be managed).
I want a solution that uses ViewControllers for each subview (in case they themselves will have subviews, too).
How do I do that?
Do I need to add some sort of childViewController?
I really am at loss, most of the blog posts and SO examples simply do not work and/or are outdated and I am unsure about whether or not I got the whole View - ViewController pattern wrong.
Let's say you have two view controllers, MainViewController and TableViewController. TableVC's main view is to be a subview of MainVC's main view. In addition, you wish to pass back to MainVC which cell was selected in TableVC.
A solution is (a) make TableVC be a child to MainVC and (b) make MainVC be a delegate for TableVC.
TableViewController:
protocol TableVCDelegate {
func cellSelected(sender: TableViewController)
}
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// please note that you can do delegation differently,
// this way results in crashes if delegate is nil!
var delegate:TableVCDelegate! = nil
var someValue = ""
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// set someValue to contents in the selected cell or it's data source
someValue = "Hello World!"
delegate.cellSelected(sender: self)
}
}
MainViewController:
class MainViewController: UIViewController, TableVCDelegate {
let tableVC = TableViewController()
override func viewDidLoad() {
// make tableVC be a child of this VC
addChild(tableVC)
tableVC.didMove(toParent: self)
tableVC.delegate = self
// position tableVC.view
tableVC.view.translatesAutoresizingMaskIntoConstraints = false
}
func cellSelected(sender: TableViewController) {
print(sender.someValue) // this should send "Hello World!" to the console
}
}
This is obviously untested code, but it is based on product code. This is meant to be a shell to help you get started.
I am having a UITableViewController with static cells. When I am performing a push segue, the animation is somewhat choppy. I have figured out which line of code is giving the problem. In viewWillAppear(_:) method of the UITableViewController, I am setting self.tableview.isHidden = true. If I remove this line of code then it works fine. However, I need this line as I am making a network call and I want to show the tableview only after the response is received. Any solutions to this issue would be appreciated.
You should set the TableView's Hidden property from the Storyboard. You can find the checkbox for this under "View > Drawing" in Attributes inspector. You can find the screenshot for this here.
That being said, you should find a better approach to indicate that API calls are being made. I would use a protocol that your viewcontrollers could conform to.
protocol ActivityIndicating {
func showLoading()
func hideLoading()
}
And in your ViewController class, you would have something like this
class ViewController: UIViewController, ActivityIndicating {
//protocol methods
func showLoading() {
//implement logic to hide tableview, show indicator, etc.
}
func hideLoading() {
//implement logic to show tableview, hide indicator, etc.
}
func someFunctionThatMakesAPIcalls() {
showLoading()
//makeAPICall and call hideLoading() once the api succeeds or fails
}
}
I've read here that if I have UITextField in my table cells, the table scrolls automatically to the cell that contains them. This works perfectly.
Making a UITableView scroll when text field is selected
Is there a way to get this to work with a UIViewController? I'm using a UIViewController because I have a lot of custom UI that needs to be laid out on top of the table view. Thanks!
I would recommend splitting your viewController into several using containerViews.
That way, you can use a UITableViewController for your tableView and use a regular UIViewController for all the custom UI.
Another way would be to set a scrollView's contentOffset manually when a textField is in focus.
It would look something like that.
#IBAction func textField(didBeginEditing sender: UITextField) {
let point = CGPoint(x: 0, y: textField.frame.minY)
scrollView.setContentOffset(point, animated: true)
}
Good day. I am not sure what I'm doing wrong in here, but I'm trying to color my image in viewWillAppear and then I when I click on a button it segue to the next controller. However when I colored, it's changing but when typing my button to segue it's breaking. Here's my code:
#IBOutlet weak var welcomeLabel: UILabel!
#IBOutlet weak var logoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
let logo = UIImage(named: "UnifiedLogo.png")
if let imageForLogo = logo{
let templateImage = imageForLogo.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
print(templateImage)
logoImageView.image = templateImage
logoImageView.tintColor = UIColor.white
}
}
and the breaking line is shown in the bellow pic.
breaking point with error message
debug screen
I have checked that outlets are linked and they are all.
Any help will be appreciated.
The code is working fine one thing you will have to check is if the outlet of imageview is connected properly or not.
If you look at Apple documentation, the view isn't added yet in the view hierarchy when viewWillAppear is called :
viewWillAppear(_:)
This method is called before the view controller's view is about to be added to a view hierarchy and before any animations are configured for showing the view
Thus, you can't refer to the view controller's oulets variables in it.
Instead, move your code in viewDidLoad, which is called once the view hierarchy is loaded :
viewDidLoad()
This method is called after the view controller has loaded its view hierarchy into memory.
I have this hierarchy:
View controller --> Scroll view --> view --> some labels
My view is (inside the scroll view) is hidden when keyboard is opened, so I used a scroll view to overcome that problem.
I connected my scroll view as an outlet to my View controller, set the content size and activated the scroll. It still does not scroll. This is my view controller code:
import UIKit
class EditViewController: UIViewController {
#IBOutlet weak var editScroll: UIScrollView!
#IBAction func backButton(_ sender: UIButton) {
self.navigationController?.popViewController(animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
editScroll.isScrollEnabled = true
editScroll.contentSize = (editScroll.superview?.bounds.size)!
print(editScroll.contentSize) // this prints the correct numbers!
}
}
The frames may not be calculated yet in viewDidLoad. Put your code in viewDidAppear or even better: viewDidLayoutSubviews.
if you want to get screen size, just use this:
UIScreen.main.bounds.size
and there is a open source about keyboard hide and show's problem.
maybe can use this one to resolve it.
https://github.com/hackiftekhar/IQKeyboardManager