How to display a UITextView programmatically? - swift

I am trying to display a basic UITextView programmatically. The problem is, if I want to display a UILabel with the same constraints and settings, it's all fine, I can have it displayed. However, if I change it to a UITextView, it just disappears. I created an empty project, just to check it, but still, no avail, just does not display.
Here's my code that works fine for a UILabel:
view = UIView()
view.backgroundColor = .systemBackground
explanationView = UILabel()
explanationView.layer.zPosition = 1
explanationView.translatesAutoresizingMaskIntoConstraints = false
explanationView.numberOfLines = 10
view.addSubview(explanationView)
NSLayoutConstraint.activate([
explanationView.centerXAnchor.constraint(equalTo: view.layoutMarginsGuide.centerXAnchor),
explanationView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
explanationView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
explanationView.bottomAnchor.constraint(greaterThanOrEqualTo: view.layoutMarginsGuide.bottomAnchor, constant: -20)
])
I am using layer.zPosition to display it over a UIImageView. I also add .isScrollEnabled for the text view. I also tried creating the UITextView via a computed property, but did not have any luck either.
Any help is appreciated.
Edit: Below is the code that I use for the text view.
explanationView = UITextView()
explanationView.layer.zPosition = 1
explanationView.translatesAutoresizingMaskIntoConstraints = false
explanationView.isScrollEnabled = true
view.addSubview(explanationView)

Related

Disclosure indicator in tableView cell isn't showing

I have added cell.accessoryType = .disclosureIndicator in my cellForRowAt delegate, and I have also ticked it in the viewController UI options under "accessory". I also added margins to the tableView so that it's 0 in relation to the parent view (that is, the device).
I even set cell.accessoryView?.tintColor = UIColor.black in case something was wrong with the color. But, still, I can't see the little arrow on the right side of the cell. I'm using a default cell. And in other viewControllers that I have it works, but in this one it doesn't.
I checked the width for both the cell and the tableview and they are both 375.
It does work if I add a custom image instead, like this:
let img = UIImage.init(named: "arrow")
cell.accessoryView = UIImageView.init(image: img)
But, I want the standard arrow.
Any more tips on what could be the issue here?
If you're targeting iOS 13 this won't work. You can verify on iOS12 but I've faced this very problem earlier this year and the solution was to add a UIButton to the cell constraining it to the trailing side of the screen.
let disclosureButton = UIButton()
disclosureButton.setImage(UIImage(named: "arrow"), for: .normal)
cell.addSubview(disclosureButton)
disclosureButton.translatesAutoresizingMaskIntoConstraints = false
disclosureButton.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -10).isActive = true
disclosureButton.centerYAnchor.constraint(equalTo: cell.centerYAnchor, constant: 0).isActive = true
disclosureButton.widthAnchor.constraint(equalToConstant: 25).isActive = true
disclosureButton.heightAnchor.constraint(equalToConstant: 25).isActive = true

Snapkit centerY constraint centers item above the center Y axis

I'm trying to make a custom UICollectionView cell class. The cell consists of a content view and a label. I want the label to be in the center of the view, horizontally and vertically, but instead the label is placed above the content view's center y axis.
I've made sure that the constraints are set, no other constraints are being set, and that the issue affects all views in the content view (I added another view and set its center Y axis as a test, and that also didn't work). I also set the content view and the label's background colors to be contrasting, and have confirmed that the label is not lying on the content view's center y anchor.
Here is how I set the consraints:
label.snp.makeConstraints{make in
make.centerX.centerY.equalToSuperview()
}
Here is what I get instead. Clearly the label is not centered vertically. You can see the blue UIView, which I added as a test, is also not centered vertically.
I used to add my constraints programmatically in this way
self.view.addSubview(image)
image.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
image.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
image.heightAnchor.constraint(equalToConstant: 30).isActive = true
image.widthAnchor.constraint(equalToConstant: 30).isActive = true
and my image is declarated in this way
let image: UIImageView = {
let theImageView = UIImageView()
theImageView.image = UIImage(named: "ico_return")
theImageView.translatesAutoresizingMaskIntoConstraints = false
return theImageView
}()
Hope it helps
Can you try Following Code.
class FilterCollectionViewCell: UICollectionViewCell {
let labelTemp = UILabel()
override func awakeFromNib() {
labelTemp.backgroundColor = .white
labelTemp.textColor = .black
labelTemp.text = "testing"
self.contentView.addSubview(labelTemp)
labelTemp.snp.makeConstraints { (make) in
make.centerX.centerY.equalTo(self.contentView)
}
}
}
Fast and easy:
myLabel.snp.makeConstraints { (make) in
make.center.equalTo(self.topView.snp.center)
}

How do I actually create a custom UISearchBar?

I have been banging my head against a wall for a day now trying to figure out how to create a custom UISearchBar so I can get rid of the stock black search bar UIKit thinks I want. I've tried a few 'solutions':
1. Customizing the appearance in the AppDelegate
//default background color for search bars
UISearchBar.appearance(whenContainedInInstancesOf: [UISearchController.self]).tintColor = UIColor(hexString: "#394C53")
This didn't work
2. Subclassing UISearchController and UISearchBar
I followed this tutorial which didn't work
3. Looping through subviews
let results = DestinationSearchResultsTableViewController()
results.mapView = map
results.handleMapSearchDelegate = self
destinationSearch = UISearchController(searchResultsController: results)
destinationSearch!.searchBar.placeholder = "Where do you want to go?"
if #available(iOS 11, *) {
navigationItem.searchController = destinationSearch
if let textfield = destinationSearch!.searchBar.value(forKey: "searchField") as? UITextField {
if let backgroundview = textfield.subviews.first {
// Below is not what I want but it works
backgroundview.backgroundColor = UIColor.white
backgroundview.layer.cornerRadius = 10
backgroundview.clipsToBounds = true;
}
}
} else {
self.navigationController?.pushViewController(destinationSearch!, animated: true)
}
destinationSearch!.delegate = self
destinationSearch!.searchResultsUpdater = results as UISearchResultsUpdating
This actually kinda works. It works really well if I use the UIColor predefined colors like UIColor.white UIColor.red etc. but it works really terribly if I want to use a specific color like this: I tried using RGB and hex representations of the color above, but all I get is black.
Here is what I want:
I want to create my own UISearchBar with a left-aligned label and content textfield to the right as I have shown above.
Thanks

Setting constraints on UITableView inside UIView

I have a UIViewController that has some base controls and in the center has a UIView (as container of swappable ui controls). I swap out the UI controls in this center UIView (container) depending on what the user is trying to do. All of the UI controls that go in to the UIView container are defined programmatically and I use programatic constraints to place them inside the UIView container.
This works fine for all of the sets of UI controls I have done so far. Now I am adding a set of controls to the UIView container that includes a UITableView
I cant figure out how to get the TableView to show up inside the UIView programatically. I can define say a button and label and run the app and see the container with the button and the label. If I add the UITableView as below then the container just does not show up at all.
// tableView
tableView.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: inputsContainerView.bottomAnchor).isActive = true
tableView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
tableView.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor, multiplier: 1/2).isActive = true
prior to the above code I have already added all of the needed controls to the container subview ...
// Add controls to the view
inputsContainerView.addSubview(listTextView)
inputsContainerView.addSubview(listImageButton)
inputsContainerView.addSubview(listImageClear)
inputsContainerView.addSubview(tableView)
If I leave off the tableview then the container shows up with the other three fields. If I add the tableview then the container and all the other three controls are gone.
How do I add the tableView to the UIView and have it show up?
Here is how I defined the UITable view
let tableView: UITableView = {
let tv = UITableView()
return tv
}()
as a compare, when I define others controls like this they show up fine after adding to the subview and setting the constraints programatically
e.g.
// DEFINE
let listTextView: UITextView = {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.text = ""
textView.textColor = defaultTextColor
textView.font = subtitleFont
textView.layer.borderColor = UIColor.black.cgColor
textView.layer.borderWidth = 1
textView.textAlignment = NSTextAlignment.left
return textView
}()
then later
// Place - with constraints
// listTextView
listTextView.leftAnchor.constraint(equalTo: inputsContainerView.leftAnchor, constant: padFromLeft).isActive = true
listTextView.topAnchor.constraint(equalTo: inputsContainerView.topAnchor, constant: 10).isActive = true
listTextView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor, multiplier: 9/16).isActive = true
listTextView.heightAnchor.constraint(equalTo: inputsContainerView.widthAnchor, multiplier: 5/16).isActive = true
Just added my comment as detailed answer, so others can see the solution faster and benefit from it.
So taken from the apple documentation, to set your own constraints programmatically, you need to set translatesAutoresizingMaskIntoConstraints to false:
Note that the autoresizing mask constraints fully specify the view’s size and position; therefore, you cannot add additional constraints to modify this size or position without introducing conflicts. If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to false, and then provide a non ambiguous, nonconflicting set of constraints for the view.
So in your case you miss to set it for your table view, when you define it. Just add this line to it:
tv.translatesAutoresizingMaskIntoConstraints = false

Swift, hide overflowing text

I have a label with a single character that I wish to be bigger than the UIView that it's a subview of. However, I need to hide the overflowing parts of the character.
For an example, this is the result I'm trying to achieve:
Where the character/Icon is the tags in lighter green in the background
Like the above example I'm using the font called "fontawesome" and their icon set. However in Swift I havn't been able to find any options to hide the overflowing parts.
Here's the current code:
var actionBox = UIView()
var actionLabel = UILabel()
var actionIcon = UILabel()
// #actionBox
actionBox.translatesAutoresizingMaskIntoConstraints = false
actionBox.backgroundColor = UIColor.formulaGreenColor()
cellView.addSubview(actionBox)
actionIcon.translatesAutoresizingMaskIntoConstraints = false
actionIcon.font = UIFont(name: "fontawesome", size: 80)
actionIcon.text = ""
actionIcon.textColor = UIColor.colorWithHex("#13E6A7")
actionBox.addSubview(actionIcon)
I know I can technically make another 2 UIViews, with a background color, and layer those on top. But that's not exactly an elegant solution.
So how can I hide the rest of the label, that's overflowing it's superView?
Any help would be greatly appreciated!
You are searching for clipsToBounds property:
view.clipsToBounds = true
Where view is your container view.