UITableView cell background - swift

I tried using the code below for setting the background for cells. It works fine but it obscures the disclosure indicator. How do I pull the disclosure indicator forward so that it is visible?
cell.backgroundColor = UIColor.clearColor()
let imageView = UIImageView(frame: CGRectMake(0, 0, cell.frame.width, cell.frame.height))
let image = UIImage(named: "sand background 1.png")
imageView.image = image
imageView.alpha = 0.5
cell.addSubview(imageView)
cell.sendSubviewToBack(imageView)

When I do this, the disclosure shows up fine. I'd personally do insertSubview(atIndex: 0) rather than addSubview and sendSubviewToBack if I wanted to manually add the background image view in the view hierarchy manually. Or, I would just set the cell's backgroundView (and selectedBackgroundView). But all of these approaches have the disclosure indicator visible (assuming that the disclosure indicator was turned on) for me. I'd run the app and then use the view debugger and carefully examine the view hierarchy and confirm that the disclosure indicator is really there:
You can then select the debug navigator in the left panel and choose the "View UI Hierarchy" from the button in the top right corner of the debug navigator:
This way you can confirm that the disclosure button is really there, or whether the disclosure indicator is simply not visible (e.g. its color might be too close to your sand-colored background to stand out).
If the problem is that the color of the accessory view is too similar to the background color, you can change the accessory view (see https://stackoverflow.com/a/27971576/1271826). For some accessory types (namely the details or checkmarks), you can change the color simply by changing the tintColor of the tableview. If you want to change the color of the disclosure indicator, you may have to replace the accessory view with a disclosure image that you created yourself, e.g.:
cell.accessoryView = UIImageView(image: accessoryImage)
You can either build this accessory image and add it as an asset to your project, or you can define an accessory image that you build dynamically. For example, here is a yellow disclosure accessory image:
lazy var accessoryImage: UIImage = {
let rect = CGRect(x: 0, y: 0, width: 10, height: 43.5)
let insetRect = CGRectInset(rect, 2, 15)
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
UIColor(red: 1, green: 1, blue: 0, alpha: 1).setStroke()
let path = UIBezierPath()
path.moveToPoint(CGPoint(x: insetRect.origin.x, y: insetRect.origin.y))
path.addLineToPoint(CGPoint(x: insetRect.origin.x + insetRect.size.width, y: insetRect.size.height / 2.0 + insetRect.origin.y))
path.addLineToPoint(CGPoint(x: insetRect.origin.x, y: insetRect.size.height + insetRect.origin.y))
path.lineWidth = 2
path.stroke()
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}()
That yields:

Related

How to add red dot badge in table view cell?

Try to add red dot badge for every unread data in inbox tableviewcell.
I try using cell.accessoryview to add badge
let size: CGFloat = 9
let width = max(size, 0.7 * size * 1) // perfect circle is smallest allowed
let badge = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: size))
badge.layer.cornerRadius = size / 2
badge.layer.masksToBounds = true
badge.textAlignment = .center
badge.textColor = UIColor.white
badge.backgroundColor = UIColor.red
if viewModel.sortedInboxItems[indexPath.section].isRead {
cell.accessoryView = badge
}
But if using cell.accessoryview it will change the display like image below (TIME in the right corner of the cell is moving forward). How to make it not change the display?
EDIT
Try to create dot as uilabel in custom uitableview cell like image below
But the result show like this image below. The red dot shape is not good enough? Can someone help with this issue ?
The accessoryView is not part of the contentView of the cell. If you set the accessoryView it will push the contentView over to make room for itself. More information on that can be found here; this diagram is helpful:
If you don't want it to do this, put your red dot into the cell itself instead of using the accessoryView. It's unclear how you've built your cells, but it looks like you've created a custom UITableViewCell, so you should be able to do this without trouble.
Or as commented above, you could include your time label in your accessory view alongside the red dot if applicable.
Consider using a UIView with corner radius just like you did with the label. To make sure that the shape is right (sizes have initialised properly) change its corner radius in an overriden layoutSubviews.
override func layoutSubviews() {
super.layoutSubviews()
badgeInboxView.layer.cornerRadius = badgeInboxView.frame.height/2
}

How to make UINavigationBar shadowImage fixed?

I have a reversed UITableView:
tableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi))
NavigationBar setup:
navigationBar.shadowImage = UIImage()
navigationBar.layer.masksToBounds = false
navigationBar.layer.shadowColor = Assets.Colors.black.color.withAlphaComponent(0.2).cgColor
navigationBar.layer.shadowOpacity = 0.7
navigationBar.layer.shadowOffset = CGSize(width: 0, height: 2.0)
navigationBar.layer.shadowRadius = 5
navigationBar.isTranslucent = false
view.backgroundColor = color
Whenever I scroll to the bottom of my TableView (to the top when inverted), shadow disappears. I want it to be constant (like at the second screenshot).
Is it possible to make UINavigationBar shadow static regardless of TableView scrolling?
How it looks now:
No shadow
How it should be:
With shadow
In iOS15/Xcode13, there is a common problem with the navigation bar's appearance. You can read more here and apply the fixes.

Label is not affected by default darkening (highlight) while pressing a button in Swift

Background: I am creating a button with an image and a label. I add the label to the button with button.addSubview(labelName) and then I add the button to the main view with self.view.addsubview(buttonName). I am creating all views programatically and with UIKit. I do not use SwiftUI or Storyboard.
Problem: When pressing the button and holding the press, by default the button image automatically gets darker and loses color (I do not know what this animation or action is called, but I guess it's some kind of default button press/click action). The gif below shows this animation.
The problem is, only the background image of the button is affected. The label and the label background, that I added to the button, are not effected by this dim animation.
What I want to achieve: I want the label and the label background to get the same dim effect, when the button is pressed. I don't like the way the label stands out with its bright colors while the button is pressed. Do I need to recognize the click and add some kind of dim animation to all childviews of the button manually or should I avoid adding labels to buttons like I did in the code below?
Simplified code for testing:
func doStuff(){
let testbutton = UIButton(frame: CGRect(x: self.view.frame.width/4, y: 100, width: 200, height: 130))
let testImg = UIImage(named: "rand.jpeg")
testbutton.setImage(testImg, for: .normal)
testbutton.addTarget(self, action: #selector(otherStuff), for: .touchUpInside)
let label = UILabel(frame: CGRect(x: testbutton.bounds.origin.x+20, y: testbutton.bounds.origin.y+20, width: 150, height: 50))
label.text = "NOT EFFECTED"
label.backgroundColor = .red
testbutton.addSubview(label)
self.view.addSubview(testbutton)
}

place NavigationBar subview behind the NavigationBarItem and title

I want to add a view below everything that's on the navigationBar. I need to add them as subviews to my NavigationBar so that they appear on any detail ViewController.
Here is what I tried so far inside my custom NavigationBar subclass (I call this method inside layoutSubviews()):
private var backgroundView = UIView()
backgroundView.frame = CGRect(x: 0, y: 0, width: 100, height: 70)
backgroundView.backgroundColor = .blue
backgroundView.alpha = 0.7
self.insertSubview(backgroundView, at: 0)
And this is what I get:
The backgroundView appears on top of the title and the NavigationBarItem.
What can I do?
According to this post on the apple developer forum, you can do this inside the NavigationBar class (which works!):
self.subviews[0].insertSubview(backgroundView, at: 0)

Pull to refresh indicator gets miss placed when adding imageview behind nav bar

I can't figure out why this happens, but when I add a imageview behind my tableview and navigation bar, my navigation bar acts strange:
The navigation bar gets stuck in a static position and dosenĀ“t move while scrolling as it did before
The activity indicator from pull to refresh gets placed between the navigation bar button and the top of the tableview. Instead of staying on top of the navigation bars title as before.
Left picture is the bug without the imageview in the background.
Right picture show how it works perfectly without the imageview.
My code to get the clear navigation bar (Though I don't think this introduces any problem as it works fine when the imageview in the background isn't there):
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true self.navigationController?.view.backgroundColor = UIColor.clear
Found a solution.
Set the image as the backgroundview of the tableview and set the tableview to be fullscreen.
let image = UIImage(named: "myphoto")
let iv = UIImageView(image: image)
iv.contentMode = .scaleAspectFill
iv.layer.frame = CGRect(x: 0, y: 0, width: (self.tableView.superview?.frame.size.width)!, height: (self.tableView.superview?.frame.size.height)!)
let tableViewBackgroundView = UIView()
tableViewBackgroundView.addSubview(iv)
self.tableView.backgroundView = tableViewBackgroundView