UIScrollView not scrolling after setting content size - uiscrollview

I have a UIScrollView and I'm setting the frame size smaller than the Content size, and it still won't scroll. I've tried searching a lot of questions on here but each time it's usually the person wasn't setting -(void)setContentSize:(CGSize)size. I'm also calling it on -(void)viewDidLoad so not sure what I'm doing wrong. Here is my code:
self.theScrollView.clipsToBounds = YES;
self.theScrollView.scrollEnabled = YES;
self.theScrollView.frame = CGRectMake(0,19,320,434);
self.theScrollView.contentSize = CGSizeMake(322, 900);
Any help? Thanks.

Related

iOS 13 - UIPopoverPresentationController sourceview content visible in the arrow

When I am displaying some view in UIPopoverPresentationController and presenting it as popover
popoverCon?.modalPresentationStyle = UIModalPresentationStyle.popover
the content have moved upward toward and a some part is being display in the arrow.
Further I had border around the popover
popoverCon?.view.layer.borderColor = .orange
popoverCon?.view.layer.borderWidth = 1.0;
popoverCon?.view.layer.cornerRadius = 10.0;
popoverCon?.view.layer.masksToBounds = false;
it is not showing toward the part where arrow is but it displays a little of the border line in the tip of the arrow.
This was working fine until iOS 12 but in iOS 13 this issue is coming.
Any suggestions on how I can solve this?
The top of my tableView content was cut off by the arrow. This is how I fixed it in my case (code inserted in my tableViewController Swift file):
override func viewSafeAreaInsetsDidChange() {
if #available(iOS 11.0, *) {
super.viewSafeAreaInsetsDidChange()
self.tableView.contentInset = UIEdgeInsets(top: self.tableView.safeAreaInsets.top, left: 0, bottom: 0, right: 0)
}
}
My solution in Obj-C, for those who need an obj-c solution.
I had previously only popovercontroller, that was creating the error like shown in the question. I renamed it to childController for clarity and created a containing popoverController to make the solution given by #SaintMSent work in my situation of only one view originally. Also used https://stackoverflow.com/a/47076040/2148757 solution and https://useyourloaf.com/blog/self-sizing-child-views/ to resize appropriately since all of my childControllers set the preferred content size frequently.
//Create container popover controller and add child to it
UIViewController* popoverController = [[MyParentPopoverController alloc] init];
[popoverController.view addSubview:childController.view];
[popoverController addChildViewController:childController];
[popoverController setPreferredContentSize:childController.preferredContentSize];
//set popover settings on container
popoverController.modalPresentationStyle = UIModalPresentationPopover;
popoverController.popoverPresentationController.sourceRect = sourceRect;
popoverController.popoverPresentationController.sourceView = buttonView;
popoverController.popoverPresentationController.permittedArrowDirections = direction;
//Fix ios13 'bug' that Apple claims is a feature
UILayoutGuide* guide = popoverController.view.safeAreaLayoutGuide;
childController.view.translatesAutoresizingMaskIntoConstraints = NO;
[childController.view.leadingAnchor constraintEqualToAnchor:guide.leadingAnchor].active = YES;
[childController.view.trailingAnchor constraintEqualToAnchor:guide.trailingAnchor].active = YES;
[childController.view.topAnchor constraintEqualToAnchor:guide.topAnchor].active = YES;
[childController.view.bottomAnchor constraintEqualToAnchor:guide.bottomAnchor].active = YES;
[popoverController.view layoutIfNeeded];
//Show the popover
...
#interface MyParentPopoverController : UIViewController
#end
#implementation MyParentPopoverController
-(void)preferredContentSizeDidChangeForChildContentContainer:(id <UIContentContainer>)container {
[super preferredContentSizeDidChangeForChildContentContainer:container];
[self setPreferredContentSize:container.preferredContentSize];
}
#end
Note: I didn't check for ios11 compatibility because my user base is restricted to not use it.
It is definitely a feature, they want you to use safe area since iOS 11, actually, but it seems now they want to force you to use it
Had the same problem as you, this worked for me
https://useyourloaf.com/blog/safe-area-layout-guide/
Definitely a bug. When you have a situation where you use UIPopoverArrowDirectionAny you will see that the problem only exists when the arrow is at the top or left of the popover and not when the arrow appears at the right or the bottom of the popover. If you make adjustments in your code to compensate it will work if you use UIPopoverArrowDirectionUp or UIPopoverArrowDirectionLeft but will not display correctly using that adjustment when using UIPopoverArrowDirectionAny and the popup appears above or to the right of the target rectangle.
I don't have an 'answer' yet, but I have identified what's going on and why it's so hard to fix.
ios13 UIPopoverViewController showing UITableViewController - Safe Area problems / Missing parts of table
Basically, any UITableView that has headers or footers is going to be broken in iOS 13 unless there's some way to alter the _UITableViewHeaderFooterViewBackground
That is notoriously problematic and doesn't play nicely with Auto-Layout - it's been known about for years, but Apple have never fixed it or made it easier to deal with and more publicly known.
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=video&cd=1&cad=rja&uact=8&ved=0ahUKEwibouuozfvkAhVCXRUIHVGsBegQtwIIKjAA&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DajsCY8SjJ1Y&usg=AOvVaw3_U_jy9EWH2dJrM8p-XhDQ
https://spin.atomicobject.com/2016/10/12/auto-layout-uitableview/
I'm unable to push my app to the App Store until I get this sorted.. I hope someone can identify how to manipulate this view so that it stops pushing the boundaries of the table out of whack with AutoLayout which causes this safe area intrusion.
Searching on the internet I got help from following link
Twitter
so I had to add safe area and manage my views accordingly
CGFloat topPadding = 0.0;
if (#available(iOS 11.0, *)) {
topPadding = self.view.safeAreaLayoutGuide.layoutFrame.origin.y;
}
Swift:
var topPadding: CGFloat = 0.0
if #available(iOS 11.0, *) {
topPadding = self.view.safeAreaLayoutGuide.layoutFrame.origin.y
}
but I haven't got solution to the border problem of mine yet.
Edit:
Temporarily I did solved the border problem by creating an invisible view on popover and giving it same frame as safe area and drawing its border.
You should use constraints. And also pay attention to topAnchor. It must be safeAreaLayoutGuide.topAnchor. In my case, it works correctly. For example:
[NSLayoutConstraint activateConstraints:#[
[toolbar.leftAnchor constraintEqualToAnchor:self.view.leftAnchor],
[toolbar.rightAnchor constraintEqualToAnchor:self.view.rightAnchor],
[toolbar.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[toolbar.heightAnchor constraintEqualToConstant:50]
]];
Embed the contents of the popover in another view with "safe area relative margins" on. This should have -21,-21 as the origin. Turn off vertical and horizontal auto resizing. Seems to work, although you lose auto-stretching.
Setup your popover's content UIViewController like such:
NSLayoutConstraint.activate([
myContentView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
myContentView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
myContentView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
myContentView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)
])

Hide UISlider track when behind transparent thumb image

I'm currently creating a custom UISlider in Xcode. I am setting the thumb Image, min Image, and max Image for the slider. Everything works great. The design calls for the thumb image to be transparent to the background of the view. This is where my problem comes in, you can see the two sides of the slider coming together in the middle of the thumb image. I don't want it to look like this. I want the slider bars to stop a the edge of the thumb image. Any ideas as to how I can accomplish this? Any and all suggestions are welcome. Thanks.
This is the Code I'm using so far.
UIImage *thumbImage = [UIImage imageNamed:#"thumb.png"];
UIImage *minImage = [UIImage imageNamed:#"min.png"];
UIImage *maxImage = [UIImage imageNamed:#"max.png"];
minImage = [minImage resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
maxImage = [maxImage resizableImageWithCapInsets:UIEdgeInsetsMake(0,0,0,0)];
[_slider setMinimumTrackImage:minImage forState:UIControlStateNormal];
[_slider setMaximumTrackImage:maxImage forState:UIControlStateNormal];
[_slider setThumbImage:thumbImageforState:UIControlStateNormal];
I can't Post an image because I don't have enough reputation. I'll try to explain a little better. I have a Thumb Image that is a circle. The center of the circle is transparent and you can see right to the background image of my view. The track for the slider continues all the way to the center of the circle. I'd prefer if the track stopped at the outline of the circle. I hope that makes more sense.
I have not received any suggestions as to how to hide the slider track when it is behind the thumb image so I am posting my solution incase someone else has this problem. If anyone has a better way of doing this please let me know.
In order to have a transparent thumb image and not have the track connect in the center of it I had to set the slider track images to blank images and setup my own slider track image that is just going to be resized every time the value of the slider changes. Not only will I be changing the width of the custom slider track but I also will have to update the X position of the image every time I resize it so that it will connect with the end image of my slider track.
In my case I have a slider that is set to 0 and its Max is set to the Width of the slider. My custom slider track is only going to appear on the right side of the thumb image. So as you slide the thumb image to the right the bar shrinks and the left side is clear.
First I setup my Slider Thumb Image and Set the Slider Track to Blank Images.
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *thumbImage =[UIImage imageNamed:#"answerSlider.png"];
[_slider setMinimumTrackImage:[UIImage new] forState:UIControlStateNormal];
[_slider setMaximumTrackImage:[UIImage new] forState:UIControlStateNormal];
[_slider setThumbImage:thumbImage forState:UIControlStateNormal];
thumbImage = nil;
_slider.value = 0;
}
In the ViewWillApear I have a call to setup my custom SLider track that I will create.
- (void)viewDidAppear:(BOOL)animated{
[self updateSlideBarLength];
}
Inside updateSLideBarLength I Use the value of the slider to help determine the width of my slider track Image.
- (void)updateSlideBarLength{
// Get Position Of Slider
CGFloat sliderValue = _slider.value;
CGFloat thumbImageWidth = 58; // this is the width of my thumb image
CGFloat sliderControlWidth = 288.0f; // This is a constant number in my case
CGFloat sliderWidth = sliderControlWidth - thumbImageWidth - sliderValue;
CGFloat sliderBarHeight = 2.0f;
// Reset Width Of aFrame
CGFloat sliderEndY = _sliderEnd.frame.origin.y;
CGFloat sliderEndX = _sliderEnd.frame.origin.x;
CGFloat sliderBarY = sliderEndY + (_sliderEnd.frame.size.height / 2 - 1);
CGFloat sliderBarX = sliderEndX - sliderWidth + (_sliderEnd.frame.size.width/2);
CGRect aframe = CGRectMake(sliderBarX, sliderBarY, sliderWidth, sliderBarHeight);
if (_sliderBar == nil) {
NSLog(#"Slider Bar Doesnt Exist");
_sliderBar = [[UIImageView alloc] initWithFrame:aframe];
_sliderBar.image = [UIImage imageNamed:#"sliderBar.png"];
[self.view addSubview:_sliderBar];
[self.view bringSubviewToFront:_sliderBar];
}
_sliderBar.frame = aframe;
}
Lastly I make sure the updateSliderBarLength is called every time the slider value changes.
- (IBAction)sliderMoved:(id)sender {
[self updateSlideBarLength];
}
This works although I had to adjust the Max value of my slider so that the custom slider track image I created always lines up with the edge of the thumb Image. While sliding the thumb image as the value increased the more the slider track started to infringe on my thumb image. By increasing the slider value I was able to stop this from happening. Again, I'm not convinced this is the best way to do this but it works for me. Later when I have more Rep and can post Pictures I will edit this post to help everyone visualize what I am describing.
I did something similar to Sean Marraffa, although I found it easier to subclass UISlider and update the frames of my image views in thumbRectForBounds:trackRect:value using something like this:
var trackHeight: CGFloat = 2
override func thumbRectForBounds(bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect
{
let superValue = super.thumbRectForBounds(bounds, trackRect: rect, value: value)
let originY = (bounds.height-trackHeight)/2.0
minTrackImageView?.frame = CGRectMake(0, originY, superValue.minX, trackHeight)
maxTrackImageView?.frame = CGRectMake(superValue.maxX, originY, bounds.width-superValue.maxX, trackHeight)
return superValue
}
minTrackImageView and maxTrackImageView are image views I set up in viewDidLoad.

Xcode 5, why isn't the image resizing?

Hello I am trying to resize a UIImage, but even though I'm not getting any errors it is not working.
hers the code of .h file
IBOutlet UIImageView *Fish;
heres the code of .m file
Fish.frame = CGRectMake(0, 0, 300, 293);
What am I doing wrong?
Thanks for any help
The image is probably not resizing because you are just resizing the image view. Make sure in your storyboard that you make the image view (Fish), have the move ScaleToFill. I can't do screenshot due to reputation ( sorry :( )
Alternately, if your goal is not to resize the image view but to resize the image it is holding, you can do this:
UIImage *image = Fish.image;
UIImage *image = YourImageView.image;
UIImage *tempImage = nil;
CGSize targetSize = CGSizeMake(80,60);
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectMake(0, 0, 0, 0);
thumbnailRect.origin = CGPointMake(0.0,0.0);
thumbnailRect.size.width = targetSize.width;
thumbnailRect.size.height = targetSize.height;
[image drawInRect:thumbnailRect];
tempImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
YourImageView.image = tempImage;
and you would set thumbnailRect to whatever size you want.
Hope this helps! Please search Nerdy Lime on the app store to find all of my apps! Thanks!
I bet your outlet is not hooked up. In your "viewDidLoad" method, try doing this:
if(Fish)
{
Fish.frame = CGRectMake(0, 0, 300, 293);
} else {
NSLog(#"Fish is null; why did I forget to connect the outlet in my storyboard or xib?");
}
And this isn't the best way to resize your UIImageView. If you're using regular springs & struts, you can grow an outlet by clicking the springs & struts to grow based on the superview's size, e.g.:
And if you're doing AutoLayout, there's a different thing you can do (basically pin your view to all four sides of the superview).
Here is how I do it:
1) select the outlet / object you want to add constraints to (in your case, it'll be the fish image view)
2) see the segmented control at the bottom of the Interface Builder window? Click on the second one and you'll see a popover view open up with a list of possible constraints to add.
3) In my example, I'm adding constraints in my ImageView to always be 10 pixels from each edge of the superview (note the four "10"s and solid red lines meaning I'm adding four constraints).
AutoLayout is a pain to get accustomed to (and I'm still learning it myself), but I suspect that once one gets the hang of it, it'll be a powerful new tool especially as Apple brings in additional iOS screen sizes in the very near future.

How do I set the background of UIScrollView to be transparent?

What i ultimately would LOVE to do is having my scroll view contents scrolling (in the scroll view control), and have a static background (a wallpaper image).
I've tried a combination of things, none of which really yields what im looking for, not even close really.
Has anybody attempted this before?
This is actually very easy, a UIScrollView inherits from a UIView so you just need to set the backgroundColor property:
aScrollView.backgroundColor = [UIColor clearColor];
The above line of code sets the background to transparent so you can see through to whatever you want to put behind. Note also that you should do the same thing to the sub-views that you put inside the scroll-view - those views should also have a transparent background colour.
If you want a static image, use a pattern as in the line of code below. This can be a texture image smaller than the screen that will be repeated/tiled, or a full-screen image so you don't see any repeats.
aScrollView.backgroundColor = [UIColor colorWithPatternImage:anImage];
For those not having clear answer to this. It goes:
put an dummy holder imageview to the mainview and set it to the desired background image or set its backcolor as pattern, then inside this view put the scrollview and set its background to transparent.
Then you get the desired effect as with Safari on iPad for example on page scroll.
This is a code for Monotouch, but is straightforward to understand.
this.View.BackgroundColor = UIColor.FromPatternImage (UIImage.FromFile ("Images/About-bg0.jpg"));
scrollView = new UIScrollView (new RectangleF (0, 0, 320, 450));
scrollView.ContentSize = new SizeF (320, 640 + 508 + 1000);
//scrollView.BackgroundColor = UIColor.FromPatternImage (UIImage.FromFile ("Images/About-bg0.jpg"));
scrollView.BackgroundColor = UIColor.Clear;
After some quick googleing I found two links that will help you:
Google Groups discussion on this question
Blog post on how to do this.
Have you tried this,
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"content.png"]];
This one worked for me...
self.scrollView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"tileableImage.png"]];

Dynamic Results and Covering Data

Today I have a question that sprouted off of this one: Database Results in Cocoa. It's regarding using the data that was returned by a database to create a certain number of questions. I am using a form of the following code (this was posted in the question).
NSMutableDictionary * interfaceElements = [[NSMutableDictionary alloc] init];
for (NSInteger i = 0; i < numberOfTextFields; ++i) {
//this is just to make a frame that's indented 10px
//and has 10px between it and the previous NSTextField (or window edge)
NSRect frame = NSMakeRect(10, (i*22 + (i+1)*10), 100, 22);
NSTextField * newField = [[NSTextField alloc] initWithFrame:frame];
//configure newField appropriately
[[myWindow contentView] addSubview:newField];
[interfaceElements setObject:newField forKey:#"someUniqueIdentifier"];
[newField release];
}
However, now when I attempt to use IFVerticallyExpandingTextfield (from http://www.cocoadev.com/index.pl?IFVerticallyExpandingTextField), or create any large amount of text, it simply goes over the other drawn content. I looked into using setAutosizingMask: on the object, but it has not worked so far.
Thanks for any help.
EDIT: What I want the effect to look like is called "Correct TextField" and what happens is called "StackOverflow Sample" - http://www.mediafire.com/?sharekey=bd476ea483deded875a4fc82078ae6c8e04e75f6e8ebb871.
EDIT 2: And if no one knows how to use this IFVerticallyExpandingTextfield class, would anyone know if there is another way to accomplish the effect?
Do you mean this?
http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaDrawingGuide/GraphicsContexts/GraphicsContexts.html
Your question is not very clear to me but this might help ^^^.
Look at 'Modifying the Current Graphics State' on that page.
What about just exactly copying the code from the 'Correct textfield' example and use it in your application? Or start your application from the 'Correct texfield' example.
Also
A comment on http://www.cocoadev.com/index.pl?IFVerticallyExpandingTextField says:
Give it a try! You should be able to
throw this into a project, read the
files in Interface Builder, and use
the custom class pane to make an
NSTextField into an
IFVerticallyExpandingTextField. You'll
need to set the layout and
linebreaking attributes for word
wrapping for this to work.
Although expansion should work
properly when the textfield is
embedded in a subview, I'm having some
trouble dealing with NSScrollViews.
The field expands into the
scrollview's content view, but none of
the controls on the scrollbar appear.
Some help here would be appreciated.

Resources