In newer versions of iOS (maybe 9?), you can do away with custom height calculation of collection view cells, and rely entirely on flow layout’s estimatedItemSize function and autolayout to automatically find the correct height and width. However, sometimes a custom, manual, height calculation is required. Examples would be when you want to fit the width of a cell the entire width of the screen, or when you want to force a height to be 0, then you’ll need manual calculation.
As a reference for myself and others, I documented this down so no one will need to fiddle with this again in the future. So assuming you have a collection view in place, and a custom cell subclass, let’s put in the pieces to make the above image work.
Reference Code
Within the ViewController class:
// 1.
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
Whichever class you have that’s going to be doing the height calculation needs to conform to UICollectionViewDelegateFlowLayout
// 2.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! TestCell
configure(cell: cell)
return cell
}
// 3.
func configure(cell: TestCell) {
cell.titleLabel.text = "Ooh woo, I'm a rebel just for kicks, now. I been feeling it since 1966, now. Might've had your fill, but you feel it still"
cell.subtitleLabel.text = "Feel It Still, by Portugal. The Man. Pretty good song I'm listening to while writing the configure method of this cell. "
}
// 4.
let sizingCell = TestCell()
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// 5.
1. Delete the storyboard (your first step to the light side, storyboards are truly awful).
2. In Info.plist, delete the line Main Storyboard file base name
3. In the AppDelegate, modify the didFinishLaunchingWithOptions function to make your view controller the root view controller of the window, and then make the window visible.
http://nantingyang.com/wp-content/uploads/2018/05/logo-small.png00nanting3243http://nantingyang.com/wp-content/uploads/2018/05/logo-small.pngnanting32432017-10-14 09:53:152017-10-14 11:28:38[iOS] How to Start the App from a View Controller Rather than Storyboard
I ran into another interesting memory issue while working on the Photobooth app. This time I was testing a template that took 4 photos, and right as the photos finished and I pushed the images to the print view controller, the app crashed. The console message said something about memory issues, so I immediately booted up trusty ol’ Instruments, and reran.
Turns out, when the print view controller is loading, my app was trying to allocate a whopping 1.26 to 1.5 GB of memory. What!!
Digging in into the Call Tree, the culprit was UIGraphicsBeginImageContextWithOptions, and its submethod CGBitmapContextCreate.
Looking through my code and commenting things out and rerunning, this was the innocuous line that caused all the trouble:
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
The key part is the scale. Setting a scale of 0 is to use the default phone scale. In my case, I was testing with an iPhone 6+, so that means 3x. The function calling this creates the final image that gets printed, and I was using the same resolution as the original camera image, so about 4860 x 7025. At 3x, that’s:
which is apparently blown by up by 10x to create the image context. I don’t really understand what’s happening underneath here.
Since this wasn’t an image I was displaying at full resolution on the phone though, 3x scale is unnecessary so I changed it to 1x, and memory usage became a lot more reasonable, about 100 mb.… Read the rest
I’ve been doing some lower level graphics stuff recently for my Photo Booth app and ran into some interesting memory leaks. I had a feeling something was off so ran Instruments after coding, and sure enough, leaks were detected. Several actually. The culprits:
CGPathRef
The biggest offender by far. Forgetting to call CGPathRelease(path) after any form of CGPathCreate…() was the most comment mistake. An interesting case also came up with holding onto an instance variable of the path. So I had this path that was expensive to calculate and gets reused, so I save it into an instance variable:
@property (nonatomic) CGPathRef scaledActivePath;
But when it does get recalculated, I want to release the previous saved path, so I override the setter:
In this case, I’m creating a color picker by calculating r, g, b values and placing them into a UInt8 * array, which is then used to create a CGDataProviderRef and CGImageRef.
Another birthday in my 30’s, and I’m sick this time, which isn’t very auspicious. All the planning and excitement about going to Tahoe to snowboard on my birthday vanished when I began feeling weak the day before, then completely useless the day of.
The human body is so weak when sick. I barely had enough energy to stand and brush my teeth. I had to lean against the counter, closing my eyes as I brushed because it was 9pm and I was already exhausted. How much it reminded me that I’ve wasted so much time and how little time I have left.
If I got lucky, and lived until about 65, the age at which the body is still able to perform when not sick, then I’ve got about 35 good years left.
Minus 3 years for sickness, and I’ve got 32 years.
Minus 12 years of birthing and childcare, assuming 2 children, and I’ve got 20 left.
God, I’ve wasted so much time. Only 20 years left to do everything I still dream of doing. 20 years to travel the world, painting the scenes that I see. Code all the programs I think of. Start a company, fail, keep trying at it, maybe succeed, maybe not, but at least I tried. Climb mountains, meet people from different walks all over the world, try different lifestyles. I want to make a video game, doesn’t have to be flashy, but something fun and original. Buy some land, build my own house. Try different sports. Go back to the same beautiful spot in the woods everyday to paint a picture.… Read the rest
http://nantingyang.com/wp-content/uploads/2018/05/logo-small.png00nanting3243http://nantingyang.com/wp-content/uploads/2018/05/logo-small.pngnanting32432017-04-23 09:35:262017-04-23 09:35:26Age and Health and Time Left
Working in engineering at various sized companies has taught me that hiring is one of the clearest ways a company’s true colors come out. How a company approaches referrals, hiring decisions, conflicts of interest, and transparency has a direct impact on employee morale. It is especially powerful, because it’s something that employees are directly involved and invested in, and affected by. However, it can swing in either direction, either increasing employee loyalty and feelings of ownership, or leave people feeling disengaged and powerless.
In the good scenarios I’ve been in, referrers did not have a say in hiring decisions. Though they gave feedback about this person they had worked with before, the hiring decision was not up to them. The decision was left to the people who would be working with the person day to day. My feeling after the process was that I was treated fairly and I had a say in what happened here. It gave me a feeling of responsibility. One, I have a say in who I’d be working with, and two, who has an impact on the company that I had invested myself in.
On the opposite end of the spectrum, poor situations have included opaque hiring decisions that were the basis of a single powerful person’s say, sometimes against the recommendation of all others who interviewed. It’s like saying, “Your vote doesn’t count”. It’s a little cut, but one in an important place. Why would I continue to invest in a place that discounts my opinion. On top of that, what a waste of everybody’s time if it didn’t matter anyway.… Read the rest
http://nantingyang.com/wp-content/uploads/2018/05/logo-small.png00nanting3243http://nantingyang.com/wp-content/uploads/2018/05/logo-small.pngnanting32432017-04-18 23:45:582017-04-18 23:52:23Thoughts on Hiring
[iOS] UICollectionViewCell custom heights with autolayout and multiline labels
(I tested this with iOS 9, 10, and 11)
In newer versions of iOS (maybe 9?), you can do away with custom height calculation of collection view cells, and rely entirely on flow layout’s
estimatedItemSize
function and autolayout to automatically find the correct height and width. However, sometimes a custom, manual, height calculation is required. Examples would be when you want to fit the width of a cell the entire width of the screen, or when you want to force a height to be 0, then you’ll need manual calculation.As a reference for myself and others, I documented this down so no one will need to fiddle with this again in the future. So assuming you have a collection view in place, and a custom cell subclass, let’s put in the pieces to make the above image work.
Reference Code
Within the ViewController class:
UICollectionViewDelegateFlowLayout
[iOS] How to Start the App from a View Controller Rather than Storyboard
1. Delete the storyboard (your first step to the light side, storyboards are truly awful).
2. In Info.plist, delete the line Main Storyboard file base name
3. In the AppDelegate, modify the didFinishLaunchingWithOptions function to make your view controller the root view controller of the window, and then make the window visible.
… Read the restCGBitmapContextCreate memory issues
I ran into another interesting memory issue while working on the Photobooth app. This time I was testing a template that took 4 photos, and right as the photos finished and I pushed the images to the print view controller, the app crashed. The console message said something about memory issues, so I immediately booted up trusty ol’ Instruments, and reran.
Turns out, when the print view controller is loading, my app was trying to allocate a whopping 1.26 to 1.5 GB of memory. What!!
Digging in into the Call Tree, the culprit was UIGraphicsBeginImageContextWithOptions, and its submethod CGBitmapContextCreate.
Looking through my code and commenting things out and rerunning, this was the innocuous line that caused all the trouble:
The key part is the scale. Setting a scale of 0 is to use the default phone scale. In my case, I was testing with an iPhone 6+, so that means 3x. The function calling this creates the final image that gets printed, and I was using the same resolution as the original camera image, so about 4860 x 7025. At 3x, that’s:
4860px * 7025px * 3 * 1 byte/pixel = 102,424,500 bytes ~ 100 mb
which is apparently blown by up by 10x to create the image context. I don’t really understand what’s happening underneath here.
Since this wasn’t an image I was displaying at full resolution on the phone though, 3x scale is unnecessary so I changed it to 1x, and memory usage became a lot more reasonable, about 100 mb.… Read the rest
Manual release and Memory Leaks
I’ve been doing some lower level graphics stuff recently for my Photo Booth app and ran into some interesting memory leaks. I had a feeling something was off so ran Instruments after coding, and sure enough, leaks were detected. Several actually. The culprits:
CGPathRef
The biggest offender by far. Forgetting to call CGPathRelease(path) after any form of CGPathCreate…() was the most comment mistake. An interesting case also came up with holding onto an instance variable of the path. So I had this path that was expensive to calculate and gets reused, so I save it into an instance variable:
But when it does get recalculated, I want to release the previous saved path, so I override the setter:
And finally, it needs to be released when the view controller is finished with:
Image construction with malloc()
In this case, I’m creating a color picker by calculating r, g, b values and placing them into a UInt8 * array, which is then used to create a CGDataProviderRef and CGImageRef.
The final result looked great:
The code involved looked like:
Notice what’s missing?… Read the rest
Age and Health and Time Left
Another birthday in my 30’s, and I’m sick this time, which isn’t very auspicious. All the planning and excitement about going to Tahoe to snowboard on my birthday vanished when I began feeling weak the day before, then completely useless the day of.
The human body is so weak when sick. I barely had enough energy to stand and brush my teeth. I had to lean against the counter, closing my eyes as I brushed because it was 9pm and I was already exhausted. How much it reminded me that I’ve wasted so much time and how little time I have left.
If I got lucky, and lived until about 65, the age at which the body is still able to perform when not sick, then I’ve got about 35 good years left.
Minus 3 years for sickness, and I’ve got 32 years.
Minus 12 years of birthing and childcare, assuming 2 children, and I’ve got 20 left.
God, I’ve wasted so much time. Only 20 years left to do everything I still dream of doing. 20 years to travel the world, painting the scenes that I see. Code all the programs I think of. Start a company, fail, keep trying at it, maybe succeed, maybe not, but at least I tried. Climb mountains, meet people from different walks all over the world, try different lifestyles. I want to make a video game, doesn’t have to be flashy, but something fun and original. Buy some land, build my own house. Try different sports. Go back to the same beautiful spot in the woods everyday to paint a picture.… Read the rest
Thoughts on Hiring
Working in engineering at various sized companies has taught me that hiring is one of the clearest ways a company’s true colors come out. How a company approaches referrals, hiring decisions, conflicts of interest, and transparency has a direct impact on employee morale. It is especially powerful, because it’s something that employees are directly involved and invested in, and affected by. However, it can swing in either direction, either increasing employee loyalty and feelings of ownership, or leave people feeling disengaged and powerless.
In the good scenarios I’ve been in, referrers did not have a say in hiring decisions. Though they gave feedback about this person they had worked with before, the hiring decision was not up to them. The decision was left to the people who would be working with the person day to day. My feeling after the process was that I was treated fairly and I had a say in what happened here. It gave me a feeling of responsibility. One, I have a say in who I’d be working with, and two, who has an impact on the company that I had invested myself in.
On the opposite end of the spectrum, poor situations have included opaque hiring decisions that were the basis of a single powerful person’s say, sometimes against the recommendation of all others who interviewed. It’s like saying, “Your vote doesn’t count”. It’s a little cut, but one in an important place. Why would I continue to invest in a place that discounts my opinion. On top of that, what a waste of everybody’s time if it didn’t matter anyway.… Read the rest