How can I change sizes and x/y coords of several UIViews with constraints in one method? - ios

I have two UITableViews.
Once the left one(for first level category) is clicked the right one(for second level) appears.
A UIView with one UILabel and one UIButton appears when the secondary category is clicked. This UIView is shown in the first screenshot. Two-level category is displayed in the UILabel(which says '미디어 > 작가 / 시나리오') and 'X' is a button to delete the category from the array containing it and hide the UIView.
I set the maximum number of categories by 3. The next one shows the second set of category; which is 7 pixels apart from the first UIView. Also, the height of the rounded rectangle view is 19.
If the second one is too long to put in the same line as the first one is in, the background UIView(light blue) should expand its height and make space for the second UIView. To handle this, I got the following codes executed when the second category is added. The margin between the upper and the lower should be 7 pixels too.I didn't add the code going back to single line because even the following one doesn't work as I want.
I want the result to be somewhat like this:
//tableViewBorder: a UIImageView to separate two UITableViews
//index: a UIView to show what level of category each UITableView is for; which says '1차 분야', '2차 분야' in the screenshot
//dffcltyBtnContainer: a UIView on the bottom of the view controller. it is set to be on the bottom by constraints and its height is fixed.
lightBlueView.frame.size.height = 45
index.frame.origin.y = lightBlueView.frame.maxY + 7
catTableView1.frame.origin.y = index.frame.maxY
catTableView2.frame.origin.y = index.frame.maxY
tableViewBorder.frame.origin.y = index.frame.maxY
catTableView1.frame.size.height = dffcltyBtnContainer.frame.minY -
catTableView1.frame.minY - 44
catTableView2.frame.size.height = dffcltyBtnContainer.frame.minY -
catTableView1.frame.minY - 44
tableViewBorder.frame.size.height = dffcltyBtnContainer.frame.minY -
catTableView1.frame.minY - 44
The code work well when it is called in a UIButton action method. The next one shows what the result of the code above works in the button-triggered method. The height of the two UITableViews correctly decreased by the same amount of change of lightBlueView.
If the sum of two rounded rectangles plus 7 is bigger than the width of lightBlueView, the second one is supposed to go down..
However, this one does not work at all in the desired code block, as if it does not exist. 'lightBlueView' has its 19 pixels of height fixed by a constraint and so are its margins with other components with the same level in the UIView(the highest level in the view controller).**
I guess it is because the height of lightBlueView is set but not sure. Setting x and y coordinate of the second category view will be another big challenge thought but that isn't the issue now :(( What does not make the lightBlueView not change its height in the code block below? Or are their some better ways to implement what I want to do? Anything would be a big help to me. Thanks in advance.
//method 'displayResults' shows or hides UIViews for each selected category. I only change '.hidden' values in it.
//selectedResult1~3Text are UILabels.
//selectedCat is an array of struct with two Strings: prim and secn. This one has what categories are chosen.
switch selectedCats.count{
case 1:
///----change width of label----//
selectedResult1Text.text =
selectedCats[0].prim + " > " + selectedCats[0].secn
selectedResult1Text.sizeToFit()
///----change width of label----//
displayResults(true, d: false, t: false)
break
case 2:
///----change width of label----//
selectedResult2Text.text =
selectedCats[1].prim + " > " + selectedCats[1].secn
selectedResult2Text.sizeToFit()
///----change width of label----//
catTableView1.frame.origin.y = index.frame.maxY
catTableView2.frame.origin.y = index.frame.maxY
tableViewBorder.frame.origin.y = index.frame.maxY
catTableView1.frame.size.height = dffcltyBtnContainer.frame.minY -
catTableView1.frame.minY - 44
catTableView2.frame.size.height = dffcltyBtnContainer.frame.minY -
catTableView1.frame.minY - 44
tableViewBorder.frame.size.height = dffcltyBtnContainer.frame.minY -
catTableView1.frame.minY - 44
displayResults(true, d: true, t: false)
break
case 3:
///----change width of label----//
selectedResult3Text.text =
selectedCats[2].prim + " > " + selectedCats[2].secn
selectedResult3Text.sizeToFit()
///----change width of label----//
displayResults(true, d: true, t: true)
break
default:
displayResults(false, d: false, t: false)
break}

Related

Swift 4 reverse change height of a UIView

I would like to build a progressbar. I took a rectangular view (progressBarBckgr) and put another one in front of it (progressBar).
The one in the front should increase its height by tabbing on the correct answer within a quiz app.
func updateUI () {
let numberOfAllQuestions = allQuestion.questionList.count
print(numberOfAllQuestions) //prints 3
let progressBarBckgrHeight = progressBarBckgr.frame.size.height
let progressBarBckgrHeightInt = Int(progressBarBckgrHeight)
let progressBarBckgrHeightPiece = progressBarBckgrHeightInt / numberOfAllQuestions
progressBarOutlet.frame.size.height = (progressBarBckgr.frame.height) + CGFloat (progressBarBckgrHeightPiece)
}
So with every correct clicked answer the progressbar should increase just so far, that in the end of quiz the whole backgroundprogressbar is covered.
Example:
10 Questions
-> clicked answer fills increases the progressbar's height for 1/10
In addition to that i would like to increase the bar from the bottom to the top. As i enter the property height to increase it, it only gets bigger in direction bottom. Is there a nice turnaround trick?
Thanks!!!
You also need to move the view up by the amount of height you have increased (progressBarBckgrHeightPiece)
Also, you should set the frame directly.
progressBarOutlet.frame = CGRect(x: progressBarOutlet.frame.origin.x,
y: progressBarOutlet.frame.origin.y - progressBarBckgrHeightPiece, // Notice here
width: progressBarOutlet.frame.width,
height: progressBarOutlet.frame.height + CGFloat(progressBarBckgrHeightPiece))

Swift 4 - Editing label frame.size.height with negative number

So I have a label that I've made in Xcode's storyboard which I want to later edit in my code. I want it to simulate something like a vertical bar so I am editing its height by doing:
answerE.frame.size.height = -200
The problem comes from the negative number, I want the label to "grow" up so the height has to be negative from its original position... I have the line in code in a simple action on button press, but each time the line is executed the label moves "up" and eventually after 3-4 clicks is out of the screen.
I just want to edit its height, what is the correct way and what am I doing wrong?
My exact line in code is:
label.frame.size.height = -CGFloat(Double(x)/Double(y) * (200))
If you have added the label in storyboard, why not you use constraints to get the result.
Add leading, trailing , bottom and fixed height constraint and connect IBOutlet to height constraint. Change the constant value of height constraint at the event which you want to perform.
If I'm right, you want the label to gain height, keeping the same bottom edge, but the top edge moving up.
In order to do this, you want to change the frame.origin.y as you change the frame.size.height at the same amount, as its placement (and so top edge) is determined by its origin. So maybe make it zero height, place it where you want it in storyboard, and then when you want it to 'grow' by x:
label.frame.size.height = label.frame.height + x
label.frame.origin.y = label.frame.origin.y - x

XCode Swift 2 UITableViewCell dynamic height based on distance to center

Im trying to create a custom date day picker from a TableView where the numbers get larger as they get toward the center of the screen. For example in the following image: Date Picker example
I'm storing the cell heights and calling the following code in scrollViewDidEndDragging, scrollViewDidEndDecelerating, and of course the height changes only take place after the scroll has happened, but how could I dynamically change the cell heights as it moves?
let pathForCenterCell = self.tableView.indexPathForRowAtPoint(CGPointMake(CGRectGetMidX(self.tableView.bounds), CGRectGetMidY(self.tableView.bounds)))
self.cellHeights[pathForCenterCell!.row - 2] = 88
self.cellHeights[pathForCenterCell!.row - 1] = 120
self.cellHeights[pathForCenterCell!.row] = 160
self.cellHeights[pathForCenterCell!.row + 1] = 120
self.cellHeights[pathForCenterCell!.row + 2] = 88
And how should I setup constraints so that the boxes in the cells and numbers grow along with the cell height and maintain the same space between them horizontally (see the above image)

How can I horizontally center two side-by-side UILabels?

I have a series of labels that I want to center horizontally (that is, along the X axis), like this:
thing1: value1
thing2: value2
etc.
Autolayout doesn't seem to allow this. Even if I stick the two together and use the guidelines to center the pair, the center constraint only applies to the first label in the pair.
The various "things" will have different lengths, and I want to colons to line up (right-justified) and the values on the left to line up (left-justified).
Is there any way to do this?
This is easy to do in code. The x-offset of the first label should be half the difference between the width of the parent view and the sum of the widths of the two labels. For example:
CGFloat xOffset = ((parentView.frame.size.width -
(view1.frame.size.width + view2.frame.size.width)) / 2);
// now position the first label using this offset
view1.frame = CGRectMake(xOffset,
view1.frame.origin.y,
view1.frame.size.width,
view1.frame.size.height);
// and position the second view relative to the first
view2.frame = CGRectMake(CGRectGetMaxX(view1.frame),
view2.frame.origin.y,
view2.frame.size.width,
view2.frame.size.height);

iCarousel - How to shift the focus to the left side

I need to implement iCarousel in a way so that it looks like this:
I have done all the modifications at my end to make it look like this but now the problem is that iCarousel works with the center image in the focus. Can I make it so that if there are only two images, they don't appear in the center but rather on the left? Think about it like the "left indented" content.
How do I do this?
iCarousal provide a property to sift focus left or right by set the width offset.
For right side use this code for swift 2.3 -
let widthOffset: Float = -120.0
self.customCarousel.viewpointOffset = CGSize(width: CGFloat(widthOffset), height: CGFloat(0))
This should be the property in iCarousel you are looking for viewpointOffset
Example...
// Modifiy widthOffset so it works well in your case
float widthOffset = 100.0;
[_yourCarousel setViewpointOffset:CGSizeMake(widthOffset, 0)];
The viewpointOffset property doesn't really work that way. It will let you align to one edge, but then when you scroll to the end you'll have the same problem.
iCarousel wasn't designed to do this. I suggest you switch to SwipeView instead (http://github.com/nicklockwood/SwipeView) which has the same delegate/datasource interface, but has an alignment property that you can use to set edge alignment, like this:
swipeView.alignment = SwipeViewAlignmentEdge;
Visit https://github.com/nicklockwood/iCarousel/issues/142
it may help.
nicklockwood (author) answer:
You could use the delegate and create a custom transform that offsets all of your views by a negative amount. Something like this:
- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform
{
float OFFSET_WIDTH = ...; // set this to about half the width of your view
return CATransform3DMakeTranslation(offset * itemWidth - OFFSET_WIDTH, 0, 0);
}
The only problem would be that when you reach the rightmost end of the
carousel there would be a gap, but you could use placeholder views to
fill the gap up.
I tripped over the same problem. After simple math I've found a more accurate answer. I've put this code in my viewDidAppear() function, because when I put it in viewDidLoad() the view.frame.width and view.frame.height took the original width of my storyboard, which didn't fit to bigger devices.
My use case was the following. My iCarousel items are simple squares. That means, I have for example a height of 3 and a width of 3. But the width of my iCarousel view is 5. In sum I have 5-3=2 space, 1 left and 1 right (because we know it's default is centered). So last step is to divide with 2 to get the width on one site = 1. With this knowledge we just have to set the viewPointOffset to 1 (in this case).
Final formular: let widthOffset = (view.frame.width - view.frame.height) / 2
Example in my code:
let widthOffset: Float = Float((mDetailCarousel.frame.width - mDetailCarousel.frame.height) / 2 )
mDetailCarousel.viewpointOffset = CGSize(width: CGFloat(widthOffset), height: CGFloat(0))

Resources