Issue with section header and table view cell in UITableViewController - ios

I've done an experiment of creating a screen with the use of UITableviewController instead of using scroll view reason is the fields in screen may get dramatically change that's why I do that
Screen :
All of those cells are static cells.
section header code
let backgroundImage = UIImage(named: "main_bg")
let imageView = UIImageView(image: backgroundImage)
self.tableView.backgroundView = imageView
header.backgroundColor = UIColor.clear
let lblheader : appLabel = appLabel(frame: CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: header.frame.height - 20))
lblheader.text = "SIGN UP"
lblheader.textFontsize = 14
lblheader.textFontType = 2
lblheader.textFontColor = 1
lblheader.textAlignment = .center
header.addSubview(lblheader)
let btnback : appButton = appButton(frame: CGRect(x: 0, y: lblheader.frame.origin.y, width: 50, height: lblheader.frame.height))
btnback.backgroundColor = UIColor.clear
btnback.setImage(UIImage(named: "back_arrow"), for: .normal)
btnback.addTarget(self, action: #selector(self.btnBackTapped), for: .touchUpInside)
header.addSubview(btnback)
Now when I scroll the table It looks as below:
I want to scroll static cell of the table under header section.
I know I can also use combination of UIViewController which contains Container and represents the Table view controller (Ref : See this i used it already)
If any solutions other than that.
Please guide me!
Thank you

alternatively you can use UITableView's tableHeaderView instead of using UITableView's viewForHeaderInSection because Section Headers WILL always stick to the top of the tableview unless otherwise if you do some simple hacks
If you make your SectionHeader opaque and not transparent/translucent you'll understand. Try making a Custom Project (test project) where you create a TableView with a lot of Sections With Different Headers
Perfect example without creating the Sample Project would be the Phone Application (the green one) in your iPhone where the Letters are Section Headers and they stick at the top of your screen when scrolling
This is an example in Swift 2.3
let someHeader = NSBundle.mainBundle().loadNibNamed("", owner:self, options nil!)!.first as! SomeView
//this is not a real function just what you wanna do stuff
someHeader.customizeIfNeeded ... yadda yadda set frame assign values add targets etc
tableView.tableHeaderView = someHeader
tableView.reloadData()

Use UIViewController instead of UITableViewControllerand add a UIView as header in top of tableView
Refer this maintain the header of a tableView fixed
Just an easy approach, hope this helps
If you have to use 'UITableViewController' look at below solution also
UITableViewController (static cells/keyboard handling) and have a fixed header

Related

how to change size of customView passed as UICalanderView Decoration?

I could not find much detail about how to add a customView as decoration for UICalenderView. There are many blogs telling how to add images but could not find anyone about CustomView. In images, we can return the decoration item with size parameter however in case of customView there is no option to pass size along with customView that you are adding. So in the end, I was able to add a view with red background, but the size is wrong. I tried to create a view and give it frame but it had no effect. So im confused how to adjust its size. Here is the method in which I add customView that im creating:
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
return .customView(addActivityCircle)
}
And this is my addActivityCircle method which for now just creating a view with red background color:
private func addActivityCircle() -> UIView {
let view = UIView()
view.backgroundColor = .red
view.clipsToBounds = false
view.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
return view
}
When I run this code I do see a view with red color but it's like a small rectangle, not 50x50. If I pass small values like 20x20, I do see a small rectangle but anything above that I see a rectangle of fixed size. I think that's the limit of decoration item but in apps like Fitness app by apple, there are bigger activity rings than that so there should be a way to have bigger sized custom views as this is just too small. The width is fine but the height is just too less. This is what im getting and it does not get any higher than that:

bringSubviewToFront not working with dropdown view (UIView)

I have a dropdown view (it'a UIView with a UITableView fully embedded in it). The top anchor is programmatically constrained to the bottom anchor of a UIButton so that when you touch the button, the dropdown view opens. See code below
However, my problem lies in the fact that the height of the open dropdown view is 150, and the only part shown of the view is the part inside the UITableViewCell (see image), with the bottom part hidden behind the cell.
func genderDropdownViewConfig() {
genderDropdownView.backgroundColor = .red
genderDropdownView.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
genderDropdownView.translatesAutoresizingMaskIntoConstraints = false
genderDropdownButton.addSubview(genderDropdownView)
//genderDropdownButton.bringSubview(toFront: genderDropdownView)
//tableView.cellForRow(at: IndexPath(row: 2, section: 0))?.superview?.addSubview(genderDropdownView)
//tableView.cellForRow(at: IndexPath(row: 2, section: 0))?.superview?.bringSubview(toFront: genderDropdownView)
genderDropdownButton.addSubview(genderDropdownView)
tableView.bringSubview(toFront: genderDropdownButton)
genderDropdownView.topAnchor.constraint(equalTo: genderDropdownButton.bottomAnchor).isActive = true
genderDropdownView.centerXAnchor.constraint(equalTo: genderDropdownButton.centerXAnchor).isActive = true
genderDropdownView.widthAnchor.constraint(equalTo: genderDropdownButton.widthAnchor).isActive = true
//genderDropdownHeight = genderDropdownView.heightAnchor.constraint(equalToConstant: 0)
genderDropdownHeight = genderDropdownView.heightAnchor.constraint(equalToConstant: 0)
for subview in genderDropdownView.subviews {
subview.backgroundColor = .clear
}
}
I guess the problem is with the way you add the genderDropdownView to the layout.
Try to add the genderDropdownView to cell's main view by
cell.view.addSubview(genderDropdownView)
and then ask the cell's view to bring the dropdown view to front.
cell.view.bringSubview(toFront: genderDropdownButton)
Your cell's height size needs to be redefined by your dropDownView. It seems that your cell contentView's height don't have any connection with your dropDownView's height to reform itself.
I think you should update the height after the button tapped.
You can try this code to update your cell's height.
cell.contentView.size.height = dropDownView.frame.origin.y + dropDownView.frame.height
This is probably due to how your layers are defined from the storyboard, it looks like your label "current weight" is forcing your dropdown view to make itself smaller. Maybe define a height constraint for the dropdown section?

iOS: AutoLayout a dynamic number of items

I'm trying to recreate the view shown below. The difficulty for me is that some of these elements will have a different number of instances.
First item is a UILabel with variabel multi lines. There will always be axactly one of this item.
UIImageView. This there can be zero or one item of.
UIButton zero or more (at least up to 3-4).
How to achieve this?
What would be a best practice to achieve this? I had one idea to use UITableView and just put each element in a table view cell. But it feels like a bit hacky solution. Especially since I then have to remove the default styling of the table (borders and padding).
Another solution is to maybe use a UICollectionView with only one column.
Third solution is to build on the autolayout solution I have, and achieve it with a lot of if statements and for-loops. This seems like a bad solution.
So how would I achieve this (using best practices)? And is it generally a bad idea for instance to use UITableView for pure layout purposes?
Create a UIStackView and inside it another one for every item with zero or more instances
Add when you want to append say a button to the buttons stackView use this
btnsStackView.addArrangedSubview(btn)
same for UILabels and UIImageViews
Check this it may help
for i in 0...5
{
let headerView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
if(i % 2 == 0)
{
headerView.backgroundColor = UIColor.blue
}
else
{
headerView.backgroundColor = UIColor.yellow
}
self.stttq.addArrangedSubview(headerView)
}
let headerView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
headerView.backgroundColor = UIColor.black
self.stttq.insertArrangedSubview(headerView , at:0)

How do I create dynamic views in swift?

I am making an IOS app where the main layout is a UITableView, and cells are completely dynamic and loaded from server. Each tableview item is a different layout.
For example, lets take first item of the tableview:
Server tells it should have a label, 2 buttons and a textbox, it should be created by code. I figured out how to create those elements themselves, the problem is how do I position them?
Ideally I would like to add each layout item under the previous one. And tableviewcell should wrap those, grow or collapse according to views.
I am fairly new to IOS/Swift. Is there any way to implment this easily? In android I just used a linearlayout and added views one by one. Does IOS have something like that? Or do I have to manually set heights, widths, and coordinates of all items?
Thanks in advance.
Here is some code:
if let Actions = AppData["Forms"][0]["AvailableActions"].array{
for var i = 0 ; i < Actions.count ; ++i {
if Actions[i].int == 1{
let actionButton1 = UIButton(frame: CGRectMake(0, 0, 96, 30))
actionButton1.setTitle("View", forState: .Normal)
actionButton1.setTitleColor(UIColor.redColor(), forState: .Normal)
cell.actionsLayout.addSubview(actionButton1)
}
}
}
You can do with self-sizing cells, in this case you just need to
Give proper constraints to your table view cell subviews,(i.e all
your subviews should be connected to each other and topmost
subview should have top-space constraints and bottommost subview should have bottom-space constraints).
Specify the estimatedRowHeight of your table view.
Set the rowHeight of your table view to UITableViewAutomaticDimension
For step 2-3 steps mentioned above,just add following code in your viewDidLoad -
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension
For understanding of self-sizing cells you can follow this link
http://www.appcoda.com/self-sizing-cells/

Subclassing UINavigationBar with Swift

I'm writing an app that gives a user tokens to spend and I want to display the user's current number of tokens in a UINavigationBar. What I would like to have is a label with the number of tokens, and an image of a coin in the top right corner of my navigation bar.
I've been searching for ways to customize the UINavigationBar, and have found plenty of posts related to adding an image to cover the entire bar, and changing the title. However, I can't find a simple way to do what I want.
I think I need to subclass UINavigationBar and add the text/image myself, but being new to iOS development and Swift, I was hoping that someone could point me in the right direction.
You can create a custom view contains subviews UILabel and UIImageView to show the token number and token image. Add it to right bar button item of the navigation controller.
It will look like:
Below code will create the custom view. Here you can observe that it is a local variable. However, you can manage global variable for custom view or create a whole new class and manage it independently for real-time updates to show token number.
// Custom to hold token number and image
let tokenView = UIView(frame: CGRect(x:0, y:0, width:100, height:44))
tokenView.backgroundColor = UIColor.yellow
// Label to show token number
let tokenLabel = UILabel(frame: CGRect(x:0, y:0, width:60, height:44))
tokenLabel.text = "1234"
tokenLabel.textAlignment = NSTextAlignment.right
let imageHeight = CGFloat(30)
let marginY = CGFloat((tokenView.frame.size.height / 2) - (imageHeight / 2))
// ImageView to display token image
let tokenImage = UIImageView(image: UIImage(named: "coin"))
tokenImage.frame = CGRect(x:70, y:marginY, width:30, height:30)
tokenView.addSubview(tokenLabel)
tokenView.addSubview(tokenImage)
// Add custom view as a right bar button item
let barButtonItem = UIBarButtonItem(customView: tokenView)
self.navigationItem.rightBarButtonItem = barButtonItem
To display the current number of tokens you can just set the title. In your view controller:
navigationItem.title = '\(numberOfCoins) coins"
If you want to do anything more fancy you can set your own title view instead of the standard UILabel:
navigationItem.titleView = UIView(...) // your custom view
To show the coin in the top right corner you'd set the rightBarButtonItem:
navigationItem.rightBarButtonItem = UIBarButtonItem(
image: UIImage(named:"Coin"),
style: .Plain,
target:self,
action:"tappedCoinButton:")

Resources