UIAlertController of style ActionSheet shows below status bar - ios

I want to show an alert controller of style action sheet to display the list of states in a country and that works fine.
But for some weird reason it shows action sheet below status bar partially which is not acceptable as it looks bad, how ever I can remove the status bar when displaying the action sheet which should work.
So I was just wondering is there any other way to make the action sheet stop to a particular offset from the top. I tried presenting the action sheet from the navigation controller but nothing changed.
Any comments appreciated.
Thanks,
Robin.

Try this:
var height:NSLayoutConstraint = NSLayoutConstraint(item: alertController.view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 300)
alertController.view.addConstraint(height);
Set it height to 300. Look, will it do any changes?

Related

How to implement class swizzling swift?

i have one view.xib file and it's having small container(container view) which holds all the controls like button/textfield, all the events of controls is handle by parent view.xib class file.
My requirement is at one place i need to add/show parent i.e view.xib completed screen. At one more place i need to add only container view. when i add/show container view only, control's associated events/methods doesn't works.
So i thought, if i can change class of container view with parent view.xib's class, my work can be done.
so either suggest me some other solutions or class swizzaling if it's possible to handle in this way.
basically i am adding container view on uitableview cell's container(view) my code for same is as below
if let questionContainerView = cellQuestionView.viewQuestionContainer {
// let questionContainerView = cellQuestionView
cell.viewQuestionContainer.addSubview(questionContainerView)
questionContainerView.translatesAutoresizingMaskIntoConstraints = false
cell.viewQuestionContainer.addConstraint(NSLayoutConstraint(item: questionContainerView, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: cell.viewQuestionContainer, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 0))
cell.viewQuestionContainer.addConstraint(NSLayoutConstraint(item: questionContainerView, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: cell.viewQuestionContainer, attribute: NSLayoutAttribute.right, multiplier: 1, constant: 0))
cell.viewQuestionContainer.addConstraint(NSLayoutConstraint(item: questionContainerView, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: cell.viewQuestionContainer, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 0))
cell.viewQuestionContainer.addConstraint(NSLayoutConstraint(item: questionContainerView, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: cell.viewQuestionContainer, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0))
cellQuestionView.layoutIfNeeded()
}
I believe what you are trying to do is create a re-usable UIView with your control buttons, that you can use in different view controllers. There is a great tutorial on Youtube entitled iOS Basically: Reusable UIView - Programming in Swift (Part 1).
Basically, you will want to create a .Xib file dedicated to the view that you want to re-use, with all the actions handled by that custom view class. Every time you will want your custom view, you will need to instantiate it from the Xib file and manually add it as a subview onto the container view.
Good luck and happy coding!
-- edit --
Your updated code shows that this will be part of a UITableView and you are trying to add your custom view on top of a UITableViewCell. You should instead instantiate a custom UITableViewCell and register it as reusable with the table view. This tutorial should guide you on doing just that: Custom UITableViewCell Tutorial - TableView with Images and Text in Swift
You can define your #IBAction in your custom table cell, and attach your button selectors to your action in your custom cell's nib.
Cheers!

ios swift 3 - UIAlertController width

Is there anyway to create a custom alertController that fit the width of the screen ?
I tried several things before asking this question
one of them is :
let width:NSLayoutConstraint = NSLayoutConstraint(item: alertController.view, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: view.bounds.width )
alertController.view.addConstraint(width)
But this line of code always makes a horizontal space between my alertController and the Screen.
Here is what I currently find in the Apple documents:
Appearance of Alert Views:
You cannot customize the appearance of alert views.
This disappoints me as I think the message text in alert views is too small for many users. DrPatience, in a comment above, suggests a possible workaround.
Alert Views

Dynamic number of elements in TableViewCell

I need to add labels one after another vertically and their number is dynamic. For now it works fine with this code:
let numUnitsLabel = UILabel(frame: CGRectZero)
numUnitsLabel.text = units
numUnitsLabel.font = UIFont.boldSystemFontOfSize(28)
numUnitsLabel.textColor = UIColor.redColor()
numUnitsLabel.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(numUnitsLabel)
let topConstraint = NSLayoutConstraint(item: numUnitsLabel, attribute: .Top, relatedBy: .Equal, toItem: cell.contentView, attribute: .Top, multiplier: 1, constant: 8 * CGFloat(i+1) + CGFloat(i*25) + CGFloat(i*20) - 5)
let rightConstraint = NSLayoutConstraint(item: numUnitsLabel, attribute: .Trailing, relatedBy: .Equal, toItem: cell.contentView, attribute: .Trailing, multiplier: 1, constant: -10)
cell.contentView.addConstraints([topConstraint, rightConstraint])
The cell is drawn fine. But when I add new item in the list and call tableView.reloadData the old labels are "remembered" and they are over new ones. The newly added object is put in the first place in the array and they are like one over another... Maybe my approach is bad, but if you have any suggestions please advice me.
Remember that cells are re-used, so however a cell was prepared previously, it still has all of that state. In particular, its view hierarchy (added subviews) remain. The reason for this is generally a layout of a Table Cell stays the same, and only its content is meant to be re-set in cellForRowAtIndexPath.
You're using an anti-pattern, first of all, which is why you're running into difficulty.
If you really want to clear out and re-layout the cell, remove all subviews explicitly, every time, e.g.:
https://techfuzionwithsam.wordpress.com/2014/12/23/what-is-the-best-way-to-remove-all-subviews-from-parent-viewsuper-view/
I suspect though, (admittedly this isn't CodeReview) that your design is flawed. Generally table cells don't need to grow in height with dynamic count of internal elements. You may need nested tables (!!), really just a single multi-line UITextView in each, or a table structured by sections with custom section header views.

Multiple UILabel at the same line in UIStoryboard

If there are multiple UILabels in one UIStoryboard, and they have the same centerY, which means they are at the same line. How can I use autolayout to let them fit in different screen? I hope these UILabels have same font size.
You need to add constraints. There are a couple of ways to add constraints.
If you go to the storyboard you will see a rectangle in between 2 vertical lines. If you click the the view you want to add constraints too (Like the UIView you added) and click that rectangle box thing It gives you options to add constants to the left, right, top, bottom of the view. If you click on the dropdown menu it gives you a list of views around the view your adding constraints too so that you can add constraints relative to that view.
Another way to add constraints is clicking the triangle button in between 2 vertical lines and selecting the option "add missing constraints". Auto layout will then try and determine the best constraints to add automatically.
To delete or modify constraints you can click the "show size inspector" (looks like a ruler) and in the constraints section you should see some constraints if you have added any. You can click and delete them or edit them.
Another option is adding constraints programmatically (below is an example of adding constraints to an image view in a stack view in swift):
let trailingConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: self.stackView, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: -5)
let leadingConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.stackView, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: 5)
self.stackView.addArrangedSubview(imageView)
self.stackView.addConstraint(trailingConstraint)
self.stackView.addConstraint(leadingConstraint)

iOS: Enable Navigation during loading overlay

In my xamarin iOS app I have a list view, I want to show the loading icon when it is being loading. But, I do not want to disable the whole page. I want the user to still go back if they wish to, using back navigation.
I used this as a reference.
So, I'm trying to set the CGRect Frame, to leave the navigation on the top active and disable the rest of the page during loading status.
I am using something like this: new CGRect(30, 0,0, 0) to leave 30 units from the top but it doesnt work. Can anyone help me out to have a frame to leave just navigation bar and cover rest of the page?
AutoLayout is a much better way to accomplish this task than using frames. Unless you need to target REALLY, REALLY old versions of iOS, AutoLayout is generally the way to go.
I'm assuming you are using a UIViewController and not a UITableViewController. This is an important distinction, because the UITableViewController only allows you to add to the UITableView which makes this task much more challenging.
Add this AddAnOverlay method to your UIViewController class, then call it whenever you want to display an overlay. You will probably need to put overlay in an instance variable so that you can remove it later. Remove it by calling overlay.RemoveFromSuperview() and you're done.
void AddAnOverlay()
{
var overlay = new UIView();
overlay.BackgroundColor = UIColor.Black.ColorWithAlpha(0.45f); // or whatever colo
overlay.TranslatesAutoresizingMaskIntoConstraints = false;
var label = new UILabel();
label.TranslatesAutoresizingMaskIntoConstraints = false;
label.Text = "Loading Fantastic Things!";
var spinner = new UIActivityIndicatorView();
spinner.TranslatesAutoresizingMaskIntoConstraints = false;
spinner.StartAnimating();
overlay.AddSubview(spinner);
overlay.AddConstraint(NSLayoutConstraint.Create(overlay, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, spinner, NSLayoutAttribute.CenterX, 1, 0));
overlay.AddConstraint(NSLayoutConstraint.Create(overlay, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, spinner, NSLayoutAttribute.CenterY, 1, 0));
overlay.AddSubview(label);
// can adjust space between by changing -30 to whatever
overlay.AddConstraint(NSLayoutConstraint.Create(spinner, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, label, NSLayoutAttribute.Top, 1, -30));
overlay.AddConstraint(NSLayoutConstraint.Create(overlay, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, label, NSLayoutAttribute.CenterX, 1, 0));
View.AddSubview(overlay);
View.AddConstraint(NSLayoutConstraint.Create(TopLayoutGuide, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, overlay, NSLayoutAttribute.Top, 1, 0));
View.AddConstraint(NSLayoutConstraint.Create(View, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, overlay, NSLayoutAttribute.CenterX, 1, 0));
View.AddConstraint(NSLayoutConstraint.Create(View, NSLayoutAttribute.Width, NSLayoutRelation.Equal, overlay, NSLayoutAttribute.Width, 1, 0));
View.AddConstraint(NSLayoutConstraint.Create(BottomLayoutGuide, NSLayoutAttribute.Top, NSLayoutRelation.Equal, overlay, NSLayoutAttribute.Bottom, 1, 0));
}
Notice the TopLayoutGuide and BottomLayoutGuide in the NSLayoutConstraint. These represent the top and bottom of your current view controller, so they can be used to size things so they don't hide navigation bars, tab bars, etc.
You have to add the overlay to the table view, which leads you to a centering problem. For this there are some options: recalculate the position of the overlay when scrolling, add an additional layer behind the table view which you reference with autolayout for positioning, ...
I'm using autolayout and you should avoid giving actual numbers, but it is also possible using bounds. Also be aware of if the user navigates away you have to cancel the task!

Resources