Setting alpha a group of elements in a view in SWIFT - swift

I've created a layout using the Xcode's Autolayout. I have a number of views with label and imageView inside. Is there any way to change the alpha for labels and imageView without creating outlets for all of them in ViewController in code?
Could I change the alpha for all the elements inside the view in code, not changing it for the view?

You can enumerate through a views subviews and set the alpha that way.
for v in view.subviews {
let view = v as! UIView
view.alpha = 0
}
Another approach is to use an IBOutletCollection which you can create in interface builder

Sure, there's lots of ways to handle this.
You could set up an IBOutletCollection of views who's alpha you want to change. An IBOutletCollection is really just an array of view objects that the runtime sets up for you. Beware that the order of the objects in the collection view is not guaranteed.
You could set a numeric range of tags on your views (starting with a non-zero value) and then use a for loop and the UIView method viewWithTag.
You could loop through all of a view's subviews in code and manipulate the view's alpha directly.

Related

Rotating one view and leaving another unmoved in Swift / Xcode for iOS on orientation change

I'm writing an iPhone app. For most of the scenes on our storyboard the default behaviour when the phone changes from portrait orientation to landscape orientation is fine. I.e. this is the layout change we want:
But for one of the scenes in the storyboard I do not want this layout change. Instead I want this:
I am confused about how to achieve the latter layout change. I can use size classes to ensure that the 100 pixels gap for the toolbar swaps from the bottom (portrait) to the right (landscape), but I cannot work out how to constrain the toolbar correctly, especially because the rotation needs to happen in code, e.g.
switch (UIDevice.currentDevice().orientation) {
case UIDeviceOrientation.LandscapeLeft, UIDeviceOrientation.LandscapeRight:
self.toolbarView.transform = CGAffineTransformMakeRotation(CGFloat(3 * M_PI_2))
// Reposition toolbarView into space to the right of the content's view
break
default:
self.toolbarView.transform = CGAffineTransformIdentity
break
}
What should I do to reposition the toolbar correctly?
Layout constraints constrain the frame of the given view. Let's see what the documentation says about the interplay between the frame and transform properties:
WARNING
If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
...
if the transform property contains a non-identity transform, the value of the frame property is undefined and should not be modified. In that case, you can reposition the view using the center property and adjust the size using the bounds property instead.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/instp/UIView/frame
So you cannot do this via AutoLayout. You have to use center and bounds, and do positioning from code:
-(void)layoutSubviews {
[super layoutSubviews];
self.toolbarView.center = ...
self.toolbarView.bounds = ...
}

UIViews, subviews and alpha

I have three views on top of each other inside a superview.
superview
- subview 1 (CD Case)
- subview 2 (Artwork)
- subview 3 (Shine)
when I animate the alpha property of the superview it seams to affect the alpha of all subviews i.e. while the animation is running subview 1 the CD Case shines through the artwork.
While blending all three into one UIImage solves this problem, but for performance reasons this not really an option. (The views are display in a grid view and loaded on demand.)
Is there any other way to avoid this behaviour?
You can either reverse the fade, as suggested by #debleek63. Or you can change the shouldRasterize flag on the superviews layer.
myView.layer.shouldRasterize = YES
This will make it use 'group opacity' and everything should composite as you'd expect. The first way is probably more performant, but not as 'correct'.

scaling UIScrollView contentSize to fit UIView with variable-height UITableView inside

I have a uiview with a uiscrollview as a subview in a nib.
Then, I load another uiview with a uitableview as a subview of this other uiview (among other elements inside this view) as a subview of the uiscrollview.
That is, UISCrollView -> UIView -> UITableView (and some other views inside the UIView).
And I need to do the following:
Once I know the final height of the tableview (depending on the number of cells and height of them) I need to resize the uiview containing it and, in turn, resize the contentSize property of the containing scrollview.
But I don't know at which point the final size of the tableview is known (because it can dynamically change size depending on the amount of text its cells will hold) and neither do I know by how much will the tableview exceed the uiview (which by default is 320 x 460).
I've tried setting the view containing the tableview to a height of 900 on viewdidload and setting it to sizeToFit, hoping it would shrink as tablecells are added to the tableview (assuming as cells are added the tableview's frame would scale appropriately). But this doesn't seem to work.
Any thoughts?
Thanks!
I just ran into a similar situation (UIScrollView -> UITableView) and was banging my head against it for hours. The short answer is this: the correct sizes to use as the basis of sizing things out were not available until my ViewController (governing the UIScrollView) was sent viewWillAppear:. Before then, I found that the values were set, but often wrong. (E.g., my first attempt at doing this was in viewDidLoad:, and the sizing values were changed there, but they were wrong!)
So my solution was thus:
In viewDidLoad: cause your enclosed UITableView to reloadData once you have your data in place.
in viewWillAppear: do the following (presuming tableView is the enclosed UITableView and scrollView is the enclosing UIScrollView):
tableView.frame = (CGRect){
tableView.frame.origin,
tableView.contentSize
};
// Finally, set content size based on the last element in the scrollView
// in my case, the last element IS the tableView, yours might be different
scrollView.contentSize =
CGSizeMake(scrollView.width
- scrollView.contentInset.left
- self.scrollView.contentInset.right,
tableView.top
+ tableView.height);
N.B., I was getting some very weird numbers when I checked them before viewWillAppear:; e.g., the tableView.contentSize seemed to be the product of default rowHeight * number of rows, ignoring my custom row heights and excluding any separators! Very odd.
This is just a guess, but since UITableView is a subclass of UIScrollView, can you use the contentSize property to see its overall size after a call to reloadData? You could use the size of the tableview to resize the UIView and the contentSize of the scrollView.

Objective-C Auto Adjust Subviews

I'm looking to write a method for an iPhone app that will auto adjust a UIViews's subviews Y values depending on the available space within that view. I'll try my best to explain without getting too confusing.
I have a Container view that is housing up to 3 Subviews. With in each subview is a button that removes the sub view from the container view, when the subview is removed i would like to adjust the remaining subviews to take up whatever space that has been opened by the removed subview.
Thanks in advance for any help!
One way is to make your wrapper view a custom UIView subclass. In that subclass, maintain a separate NSMutableArray of your subviews wherein each subview's array index corresponds to its position on the screen.
With this in place, you have a couple of options. One is to overide didAddSubview:. Based on the frame of the subview being added, you can determine the subview's position and insert reference to the subview at the appropriate index in your array.
A cleaner option is to implement your own custom method like this:
- (void)insertSubview:(UIView *)subview atPosition:(NSInteger)position;
where position is an index identifying which "slot" the subview should fill. You can set the frame for the subview explicitly within this method, along with any other subviews that are impacted by the insertion. Then insert the subview into your array at the corresponding index.
Finally, override willRemoveSubview:. In it you can use indexOfObject: on your array to find the position of the subview being removed. Then simply adjust the frames of all the subviews that follow it, and remove the subview from your array.
(One other alternative is to skip the array and just use the tag property to indicate the position of each subview. I don't like this option though. Using the tag property for anything always feels like a terrible hack to me.)
Well the first thing you need to do is signal your container that a subview has been removed.
Then you can take the height value of the view that was removed, divide it by the number of remaining subviews, and then expand the height of those remaining subviews.
Then you set your first remaining subview to Y coordinate 0, and the second (if there is one), to a Y coordinate of the first subviews height value

resize UITableViewCell textLabel

I have a UITableViewCell that I would like to add a view to the right (in addition to the accessory view). I tried setting the size of textLabel to be a few pixels narrower but it just resizes it back.
Is there any way to resize textLabel?
Actually it CAN be resized if you create an UITableViewCell subclass and override the layoutSubviews method:
- (void)layoutSubviews {
[super layoutSubviews]; //The default implementation of the layoutSubviews
CGRect textLabelFrame = self.textLabel.frame;
textLabelFrame.size.width = _textLabelMaxWidth;
self.textLabel.frame = textLabelFrame;
}
Hope it helps.
The object referenced by the default textLabel property, in UITableViewCell instances of type UITableViewCellStyleDefault, cannot be resized, at least not in my experience. The best idea in these cases is to create your own subclass of UITableViewCell, in code or even with Interface Builder if you want, and give it the layout that you want.
I've noticed that the textLabel resizes to accomodate the accessoryView. So if you want the label to use the entire cell, you could set accessoryView to nil (I think this is the default behavior anyway). Or, for example, if you want the label to take only the left half the cell, make accessoryView be an empty UIView that spans the right half the cell. (Doesn't have to be empty, you can put stuff in there...my point is that it WILL shrink the textLabel.)
You can do resizing UITableView Cell in this simplest way.First,take a look at my sample project.
ResizableUIView
It will show you how you can resize uitableview cell base on its inner component in simplest way by creating constraints.
tblTest.estimatedRowHeight = 100 // This is where you can set your estimated row height
tblTest.rowHeight = UITableViewAutomaticDimension
Another important fact is your label lines :
it should be 0
In order to make you understand,I set UILabel inside UIView,take a look at how I created constraints on its parent UIView.
If you still need any help,just ask.
Good Luck