How to change the uitableviews style in code in swift - ios

I want to change the uitableview's stype in viewdidiload in swift.
but it gives an error "Can not assign the result of this expression
#IBOutlet weak var tableview: UITableView!
let names = ["Gulshan","Mitesh","Rahul","roma"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any xadditional setup after loading the view, typically from a nib.
tableview.style = UITableViewStyle.Grouped
}

You can do that while initializing in init with frame method.
See example:
var tableview1 = UITableView(frame: CGRectMake(0, 0, 160,320), style: UITableViewStyle.Grouped)

You can't change the tableview style dinamically, you have to do it in your xib file or storyboard if you have one.
If you don't use a storyboard or a xib, and prefer to create the tableview programmatically, specify the style while creating the tableview using the
- initWithFrame:style: method.
Bye
D.

Related

accessing UIView subclass in view controller

Let's say I have SomeViewController: UIViewController, and I have a custom view CustomView: UIView, defined as a XIB, that I want to display. This custom view will be reused in other view controllers and even multiple times in the same view controller.
class CustomView: UIView {
#IBOutlet public var label: UILabel!
}
The way I have always added this view has been:
class UIExamples: UIViewController {
#IBOutlet private var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
let customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.frame = myView.bounds
myView.addSubview(customView)
}
}
Let's say that later on I want to modify something about the CustomView via a public property label.
I could do it inside viewDidLoad ONLY BECAUSE I have access to customView, but what if I want to change it in some other function? What I have seen is that one would have to do
let customView = myView.subviews[0] as! CustomView
customView.label.text = "some text"
which does not look right.
So, I thought the right way should be this:
class UIExamples: UIViewController {
#IBOutlet public var customView: CustomView! // Now this is always a CustomView type
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.label.text = "some text" // DOES NOT WORK!
}
}
That last line customView.label.text does not work. In fact, the label is not even seen on the screen. What am I doing wrong?
OK, didn't read (or maybe was reading before edit) that you use xib. If ViewController is created from xib with label in it this will be correct way:
set myView class in xib here:
and then connect IBOutlet (remove current one from xib here:
and then from code).
Now myView.label.text = "some text" should work without further issues.
Good luck!
If you create your view from code do it in this manner:
class UIExamples: UIViewController {
#IBOutlet private var myView: CustomView!
override func viewDidLoad() {
super.viewDidLoad()
// Assume makeViewFromNib returns the view [0] in the Nib.
myView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
myView.frame = view.bounds
view.addSubview(myView)
}
}
Because you already have property storing this view in your view controller it's unnecessary to dig inside subviews, it will work like that
myView.label.text = "some text"
And reason for
customView = makeViewFromNib(nib: "\(CustomView.self)", owner: self) as! CustomView
customView.label.text = "some text"
isn't working is because it's completely new view that wasn't added to your view controller subviews (also frame wasn't set BTW). And because you changed value of your customView property it's now not pointing to old instance of view, that is present in subviews (you can still see that "old one" but not change it).
But I really recommend to use pointer created once, as correct class to avoid casting. (Or creating view directly in xib / storyboard, otherwise #IBOutlet is not necessary)
Posting my own answer.
Create the XIB file.
Create the UIView subclass Swift file.
Under the XIB file owner's Identify Inspector custom class field, type in the UIView subclass name (your custom view).
Under the XIB file owner's Connections Inspector, make sure all IBOutlets in the Swift file are connected.
Add a view to the view controller and under its Identify Inspector custom class type, specify the custom class name.
Important:
* In your XIB swift file, you have to properly load the XIB content view.
...
/// Initializer used by Interface Builder.
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
/// Initializer used programmatically.
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
...
func configure() {
let contentView = // here use many of the functions available on the internet to
// load a view from a nib.
// Then add this view to the view hierarchy.
addSubview(contentView)
}

How to increase and decrease UIView height by codebase using Swift

In my case, I have to add UIView in top of the Tableview but it should be inside Tableview because of scrolling. Here, I drag and dropped UIView on topside tableview. Now, some scenario I need to increase and reduce height of the UIView. I tried to add constraints but its not available. How to achieve this by codebase?
Tableview with UIView Storyboard Hierarchy
Storyboard Design
Disabled Constraints For UIView
Constraints is not working with table header view. you can set table header using custom view and update its frame
Set a custom view
Set table header and update it's frame
class ViewController: UIViewController {
#IBOutlet var tableView: UITableView!
#IBOutlet var tableHeader: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
loadHeader()
}
func loadHeader() {
tableHeader.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 300)
tableView.tableHeaderView = tableHeader
}
}

Some Cells on UITableView won't auto-resize

I am experiencing a very strange phenomenon. I am using the AutomaticDimension function on my tableview and for some odd reason it works on all of my cells except for 3. All of my cells have the exact same constraints which is the weird part. I have tried changing the constraints on the cells but it appears that they are being ignored. Any insight would be great. I make sure to call the auto dimension function in viewdidload.
override func viewDidLoad() {
super.viewDidLoad()
self.TableView.dataSource = self
TableView.estimatedRowHeight = 200.0
TableView.rowHeight = UITableViewAutomaticDimension
}
Here is one of the classes that is not working:
class foursleepCell: UITableViewCell {
#IBOutlet weak var foursleepLabel: UILabel!
#IBOutlet weak var foursleepScale: UISegmentedControl!
var delegate: foursleepCellToController?
#IBAction func foursleepValueChanged(_ sender: UISegmentedControl) {
if let delegate = delegate {
let indexPath = delegate.indexOfChangedfoursleepCell(at: self)
delegate.savefoursleepCellResponse(at: indexPath, response: foursleepScale.selectedSegmentIndex)
}
}
}
Attached are images of constraints and output:
Label Constraints
Segmented Control Constraints
Actual Output
Working Output
I don't think there is anything wrong with the way you are trying to set the cell to automatically resize, it is just the fact the the top-to-bottom constraints that are required for that resizing to happen are not present at runtime. Apparently this is something that can happen sometimes in Xcode - try creating a new table view cell and setting up all the views and constraints again from scratch. Copying and pasting the table view cell into a new cell and working from the copy did not fix it for me - it behaved exactly the same. But setting it up fresh did the trick.

Get the frame of a UIStackView subViews

I have created a UIStackView in IB which has the distribution set to Fill Equally. I am looking to get the frame for each subView but the following code always returns (0, 0, 0, 0).
class ViewController: UIViewController {
#IBOutlet weak var stackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
let pView = UIView()
let sView = UIView()
pView.backgroundColor = UIColor.red
sView.backgroundColor = UIColor.orange
stackView.addArrangedSubview(pView)
stackView.addArrangedSubview(sView)
}
override func viewDidLayoutSubviews() {
print(stackView.arrangedSubviews[0].frame)
print(stackView.arrangedSubviews[1].frame)
}
}
I would think that a stack view set to fill equally would automatically set the calculate it.
Any help would be appreciated.
After reading over your code I think this is just a misunderstanding of viewDidLayoutSubviews(). Basically it is called when all the views that are descendants of the main view have been laid out but this does not include the subviews(descendants) of these views. See discussion notes from Apple.
"When the bounds change for a view controller's view, the view adjusts the positions of its subviews and then the system calls this method. However, this method being called does not indicate that the individual layouts of the view's subviews have been adjusted. Each subview is responsible for adjusting its own layout."
Now there are many ways to get the frame of the subviews with this being said.
First you could add one line of code in viewdidload and get it there.
override func viewDidLoad() {
super.viewDidLoad()
let pView = UIView()
let sView = UIView()
pView.backgroundColor = UIColor.red
sView.backgroundColor = UIColor.orange
stackView.addArrangedSubview(pView)
stackView.addArrangedSubview(sView)
stackView.layoutIfNeeded()
print(stackView.arrangedSubviews[0].frame)
print(stackView.arrangedSubviews[1].frame)
}
OR you can wait until viewDidAppear and check there.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print(stackView.arrangedSubviews[0].frame)
print(stackView.arrangedSubviews[1].frame)
}

Can't change UITableViewCell's subview's position

So I have a static tableview in place and I'd like to change the position of the label inside the first tableviewcell. I have IBOutlet for the first cell.
This is how I try to change the label's position:
UILabel *label1 = [tempTC.cell1.contentView.subviews firstObject];
label1.frame = CGRectMake(10, 10, 10, 10);
The problem is that the frame doesn't change, however I can do everything else to the label like change it's text and size etc, but changing the frame doesn't seem to work.
Is there something I am missing?
When using auto layout, you should set frames, you should change the constraints instead. The easiest way to do this is to make IBOutlets to the ones you need to change, and change the constant value of the constraint. For instance, if you had a constraint to the left side called leftCon, you could do something like this:
self.leftCon.constant = 30;
When you want to change frame subview those were constraint in XIB. You need to set translatesAutoresizingMaskIntoConstraints = YES.
label1.translatesAutoresizingMaskIntoConstraints = YES;
label1.frame = CGRectMake(10, 10, 10, 10);
For detail:
Can I use setFrame and autolayout on the same view?
First of all according to comments, disable auto layout.
Second if You want refer to textLabel use [[UITableViewCell textLabel] setFrame:CGRectMake(10,10,10,10)];
BTW. If You'r first UITablViewCell is special I suggest use .xib and subclass UITableviewCell. Apply that subclass to prototype UITableViewCell in storyboard, then add this cell protype cell as property/global variable.
If you need more description please ask :).
Make a custom UITableViewCell.
Look at the example below.
Inside tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) method I am dynamically changing TimeStatus (UIView) frame size:
.
.
.
let cell:OneTVChannelTableViewCell = tableView.dequeueReusableCellWithIdentifier(OneCurrentChannelTCIdentifier, forIndexPath: indexPath) as OneTVChannelTableViewCell
.
.
.
cell.setForRepairDynamicViewWidth(channelTimeStatusWidth)
.
.
.
And here is my simple custom UITableViewCell:
class OneTVChannelTableViewCell: UITableViewCell {
#IBOutlet weak var Number: UILabel!
#IBOutlet weak var Image: UIImageView!
#IBOutlet weak var Title: UILabel!
#IBOutlet weak var TimeStatus: UIView!
#IBOutlet weak var TimeBack: UIView!
var RepairWidth:CGFloat = 0.0
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
override func layoutSubviews() {
super.layoutSubviews()
TimeStatus.frame.size.width = RepairWidth
}
func setForRepairDynamicViewWidth(width:CGFloat)
{
RepairWidth = width
}
}

Resources