I want to display my upload progress of a file in the table view cell.
I am using Progress View programatically for the same. However, the progress view overlaps the file name and its related data. How can I make the progress view appear behind the text?
Following is the code used:
let animationProgress = UIProgressView(progressViewStyle: .bar)
var prog: Float = 0.0
animationProgress.progress += 0.5
animationProgress.rightAnchor.accessibilityActivate()
animationProgress.tintColor = .dbbSearchBarBackgroundColor()
animationProgress.setProgress(prog, animated: true)
perform(#selector(updateProgress), with: nil, afterDelay: 1.0)
animationProgress.frame = CGRect(x: 0, y: 0, width: prog, height: 85)
animationProgress.transform = animationProgress.transform.scaledBy(x: 1, y: 85)
self.contentView.addSubview(animationProgress)
Actual tableview cell :
Progress view getting overlapped :
The issue you're having is related to the order of subviews. I'm not sure what cell you are you using how and when do you add other labels. But it looks like you need to send the UIProgressView to the back.
In your case the fix should be after calling self.contentView.addSubview(animationProgress) make sure to send the subview to the back which means calling self.contentView.sendSubviewToBack(animationProgress).
Related
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:
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?
I have a uiview that is overlaying and blocking interaction with my view on top of the superview. I've tried bringing the blocked view to the front but that doesn't work either.
Here's the code for the blocking view:
self.gesstureView = UIView(frame: screenBounds)
if let gestureView = self.gesstureView, let controlDockView = self.controlDockView, let controlTopView = self.controlTopView {
gestureView.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]
gestureView.frame.size.height -= controlDockView.frame.height
gestureView.contentMode = .center
gestureView.backgroundColor = UIColor.red
self.view.addSubview(gestureView)
Heres the code for the view that's blocked:
let topHeight = screenBounds.height * 0.15
self.controlTopView = UIView(frame: CGRect(x: 0, y: 0, width: screenBounds.width, height: topHeight))
if let controlTopView = self.controlTopView {
controlTopView.backgroundColor = UIColor.clear
controlTopView.autoresizingMask = [.flexibleTopMargin]
controlTopView.addBlurEffect()
self.view.addSubview(controlTopView)
// does not work view is still hidden
self.view.bringSubview(toFront: controlTopView)
Thanks for the sample code!
The problem is that you add your gestureView to the view hierarchy after you brought controlTopView to front. So controlTopView will actually be the second view this is why it is not visible.
To solve the problem either add controlTopView lastly or bring it to the front after you've added everything.
view.addSubview(previewView)
view.addSubview(controlDockView)
view.addSubview(gestureView)
view.addSubview(controlTopView)
Just in case -- have you checked if your controlTopView is not visible simply because it has nothing visible to draw? In your code snippet, the controlTopView only has a transparent background color and a blur effect (which wouldn't do anything to the solid red behind it).
The best way to really see whats going on is to use the UI debugger in Xcode. It will show you what is obscuring what. Also, it is very likely that the UIViews are being drawn in an order you are not anticipating.
You should resize and select the hidden view....if its actually there.
I created a view programmatically, like a popup coming from the top with some text and images in there!
alert = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width , height: 0))
alert?.frame.origin.y = (textLable?.frame.height)!
alert?.frame.size.height = (textLable?.frame.height)!
alert?.backgroundColor = self.arrayOptions.colorBackground
and then I'm trying to add a UITapGestureRecognizer to that view like this inside a setup func that is called in the init.
let tap = UITapGestureRecognizer(target: self, action: #selector(self.teste))
tap.numberOfTapsRequired = 1
alert?.addGestureRecognizer(tap)
im adding that view like this in a UitableViewController:
self.popView = PopupView(frame: CGRect(x: 0 , y: 0 , width:self.view.frame.width, height: 0), with: PopUpOptions.error, originY: 0,description:"blablabla")
self.view.addSubview(self.popView!)
But when I tap on the view nothing happens, but when I tap repeatedly over and over this error occurs:
<_UISystemGestureGateGestureRecognizer: 0x174186f50>: Gesture: Failed
to receive system gesture state notification before next touch
But I cant seem to find an answer for this, could anyone help me pls!
Thank you!
here is the GitHub link https://github.com/Coimbraa/AlertsPopup_framework for my framework
Took a look at your GitHub repo - Couple notes...
I see a lot of "!" in your code. Each one of those is a potential crash. For example, I had to make a number of edits just to get it to run at all (I don't have the image assets the code is expecting).
In PopUpView.swift change the init() func to this (just added the clipsToBounds line):
override public init(frame: CGRect) {
super.init(frame: frame)
setup()
self.clipsToBounds = true
}
Now, when you call popView?.toggleStatus() you probably won't see anything.
Your PopupView "container" has a height of Zero. Without clipping its contents, you see the content, but you can't interact with it.
I changed your animation block in toggleStatus() to this:
UIView.animate(withDuration: 0.5, animations: {
if let sz = self.alert?.frame.size {
self.frame.size.height = sz.height
}
self.alert?.frame.origin.y = (self.startY)! + (self.status ? 0 : -((self.textLable?.frame.height)! + self.startY))
}) { (finished:Bool) in
// ...
and I could now tap into and edit the TextView, and tap elsewhere and get print("pressed") output to the debug console.
I did not dig further, so I don't know if/where you need to put additional code to reset the frame-height back to Zero (or maybe it gets hidden or removed, whatever).
Try this:
alert.isUserInteractionEnabled = true
Set this property to true for those views you want to tap on (where you add the tap gesture recognizer).
You are adding that Custom Alert View in Table View Controller.
First try what Tung Fam has suggested, if it doesn't work then,
Trying adding it on window like:
self.view.window.addSubview(self.popView!)
Also set the frame of the window to the popupView.
As I'm seeing you are setting target for TapGesture as self in
let tap = UITapGestureRecognizer(target: self, action: #selector(self.teste))
Here self is object of UIView (your alert view).
So according to this line your tapGesture listener must be implemented in alert? class. And you need to use custom protocol or custom delegate to get the action of tapGesture in other classes.
I am trying to create two drop down menu's side by side in swift. So far it consists of a UIView (created using a NIB) then two UIView's created in code that is used as a wrapper for the two UITableView's which will be displayed when the drop down menu is pressed. I have gotten the left hand menu (Leaderboard Menu) working perfectly but when I'm trying to create the 2nd menu the exact same way it is not displaying when the 2nd menu is pressed. For some reason if the x value of the frame is any more than 194 it is not displayed, my guess is that the 2nd menu is being added as a subview of the first but since the first's bounds is only 194 wide it is outside of the bounds to be displayed for that view. I will give a bit of code to show what I am trying to do. Thank you for any responses!
let leaderboardMenuFrame = CGRect(x: 0.0, y: 0.0, width: 194.0, height: leaderboardTableHeight)
let rankingMenuFrame = CGRect(x: 195.0, y: 0.0, width: 92.0, height: rankingTableHeight)
// Set up leaderboard DropdownMenu
self.leaderboardMenuWrapper = UIView(frame: leaderboardMenuFrame)
self.leaderboardMenuWrapper.clipsToBounds = true
self.leaderboardMenuWrapper.autoresizingMask = UIViewAutoresizing.FlexibleWidth.union(UIViewAutoresizing.FlexibleHeight)
// Set up ranking DropdownMenu
self.rankingMenuWrapper = UIView(frame: rankingMenuFrame)
self.rankingMenuWrapper.clipsToBounds = true
self.rankingMenuWrapper.autoresizingMask = UIViewAutoresizing.FlexibleWidth.union(UIViewAutoresizing.FlexibleHeight)
//Init Leaderboard menu table view
self.leaderboardMenuTableView = DropDownTableView(frame: CGRectMake(leaderboardMenuFrame.origin.x, leaderboardMenuFrame.origin.y + 0.5, leaderboardMenuFrame.width, leaderboardMenuFrame.height+300))
//Init Ranking menu table view
self.rankingMenuTableView = DropDownTableView(frame: CGRectMake(rankingMenuFrame.origin.x, rankingMenuFrame.origin.y + 0.5, rankingMenuFrame.width, rankingMenuFrame.height+300))
self.leaderboardMenuWrapper.addSubview(self.leaderboardMenuTableView)
self.rankingMenuWrapper.addSubview(self.rankingMenuTableView)
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
// Add Menu View to container view
view.addSubview(self.rankingMenuWrapper)
view.addSubview(self.leaderboardMenuWrapper)
addSubview(view)
I guess the issue is this line of code:
//Init Ranking menu table view
self.rankingMenuTableView = DropDownTableView(frame: CGRectMake(rankingMenuFrame.origin.x, rankingMenuFrame.origin.y + 0.5, rankingMenuFrame.width, rankingMenuFrame.height+300))
The origin of the rankingMenuTableView should be x = 0. But as you are using the rankingMenuFrame to init the frame of the rankingMenuTableView its origin would be x = 195. This will push your rankingMenuTableView out of bounds.
So the correct way to achieve what you want should be:
//Init Ranking menu table view
self.rankingMenuTableView = DropDownTableView(frame: CGRectMake(0, rankingMenuFrame.origin.y + 0.5, rankingMenuFrame.width, rankingMenuFrame.height+300))
Hope this helps.