I've created a custom input textView at the top of the system keyboard. When I set the textView becomeFirstResponder, there is a tiny spacing appears between my textView and the system keyboard.
So I create a new empty project and use the same code to test my custom input textView. guess what's happen? Everything goes well !!!
I'm really confused by this problem. Are there any settings I missed?
https://i.stack.imgur.com/rrR2I.png
Code:
- (void)createInputBarView{
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, SCREEN_Width, 0)];
toolBar.hidden = YES;
QInputBarView *anInputBar = [[QInputBarView alloc] initWithFrame: CGRectMake(0, 0, SCREEN_Width, UIInputBarViewMinHeight)];
[anInputBar setupWithConfiguration: config];
[anInputBar setDelegate: self];
[anInputBar.inputTextView setInputAccessoryView: toolBar];
[self addBottomInputBarView: anInputBar];}
- (void)addBottomInputBarView:(UIView *)inputBarView {
inputBarView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin);
CGRect inputFrame = CGRectMake(0.0f,self.viewController.view.frame.size.height + (belowViewController ? 0 : (- inputBarView.frame.size.height - self.safeAreaInsetsBottom)),
self.viewController.view.frame.size.width,
inputBarView.frame.size.height);
inputBarView.frame = inputFrame;
[self.viewController.view addSubview:inputBarView];
[self.viewController.view bringSubviewToFront:inputBarView];
self.inputBarView = inputBarView;}
Related
I'm trying to figure out an approach to build something like the image below, which is a list of items that when a section is clicked slides out content. It's a really common UX on most websites and what not. My idea is to have each gray box (button) slide out a UIView containing some other items. I'm still new to iOS development but I'm struggling to find how you can animate a UIView to slide down and push the content below it down as well. Hoping some one can give me a good starting point or point to some info outside the realm of the apple docs.
Thanks!
So if you just have a few views, I would not recommend the UITableView approach, since it is not so easy to customize with animations and table views usually want to fill the whole screen with cells. Instead write a expandable UIView subclass that has the desired two states. Add a method to switch between extended and collapsed state. On expanding/collapsing adjust their positions so that they always have enough space.
I provide you an example of views adjusting their frames. I guess it should be easy to do the same with auto layout constraints: give the views a fixed height constraint and change this on collapsing/expanding. The same way set the constraints between the views to be 0 so that they are stacked on top of each other.
Expandable View:
#interface ExpandingView(){
UIView *_expandedView;
UIView *_seperatorView;
BOOL _expanded;
}
#end
#implementation ExpandingView
- (id)init
{
self = [super initWithFrame:CGRectMake(15, 0, 290, 50)];
if (self) {
_expanded = NO;
self.clipsToBounds = YES;
_headerView = [[UIView alloc] initWithFrame:self.bounds];
_headerView.backgroundColor = [UIColor colorWithWhite:0.8 alpha:1];
[self addSubview:_headerView];
_seperatorView = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height-1, self.bounds.size.width, 1)];
_seperatorView.backgroundColor = [UIColor lightGrayColor];
[self addSubview:_seperatorView];
_expandedView = [[UIView alloc] initWithFrame:CGRectOffset(self.bounds, 0, self.bounds.size.height)];
_expandedView.backgroundColor = [UIColor blueColor];
[self addSubview:_expandedView];
}
return self;
}
- (void)layoutSubviews{
[self adjustLayout];
}
- (void)adjustLayout{
_headerView.frame = CGRectMake(0, 0, self.bounds.size.width, 50);
_seperatorView.frame = CGRectMake(0, 49, self.bounds.size.width, 1);
_expandedView.frame = CGRectMake(0, 50, self.bounds.size.width, self.bounds.size.height-50);
}
- (void)toggleExpandedState{
_expanded = !_expanded;
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, _expanded?200:50);
[self adjustLayout];
}
#end
ViewController:
#interface ExpandingViewController (){
NSArray *_expandingViews;
}
#end
#implementation ExpandingViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_expandingViews = #[
[[ExpandingView alloc] init],
[[ExpandingView alloc] init],
[[ExpandingView alloc] init],
];
for(ExpandingView *view in _expandingViews){
[view.headerView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(expandingViewTapped:)]];
[self.view addSubview:view];
}
}
- (void)viewWillLayoutSubviews{
int y = 100;
for(ExpandingView *view in _expandingViews){
view.frame = CGRectOffset(view.bounds, (CGRectGetWidth(self.view.bounds)-CGRectGetWidth(view.bounds))/2, y);
y+=view.frame.size.height;
}
}
- (void)expandingViewTapped:(UITapGestureRecognizer*)tapper{
ExpandingView *view = (ExpandingView*)tapper.view.superview;
[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0 options:0 animations:^{
[view toggleExpandedState];
[self.view layoutIfNeeded];
} completion:nil];
}
Using PEPhotoCropEditor I'm trying to set cropview.croprect but the rect seem to ignore it and still calculate the rect based on the image size. Meanwhile .cropRect works well if I use a controller to access it.
What I'm trying to do is create a fix cropview regardless of what image is selected.
Here's my code:
cropView = [[PECropView alloc] initWithFrame:self.view.bounds];
cropView.image = coverPhotoView.image;
cropView.cropRect = CGRectMake(0, 0, 320, 173);
[self.view addSubview:cropView];
Place your initialisation code into ViewDidLoad:
- (void)viewDidLoad
{
cropView = [[PECropView alloc] initWithFrame:self.view.bounds];
cropView.image = coverPhotoView.image;
[self.view addSubview:cropView];
}
And then set your CropRect in ViewDidAppear:
- (void)viewDidAppear:(BOOL)animated
{
cropView.cropRect = CGRectMake(0, 0, 320, 173);
}
I'm using the JASidePanels. I have set my project and storyboard to show in landscape orientation only. The result shown as below. It seems like the view are read as portrait by JASidePanels. However when i turn the device into to the other side, the panel orientation will be corrected. Please advise how to fix this issue.
Thanks.
You can add the following line in viewDidAppear() :
[self _layoutSideContainers:YES duration:0];
Try replacing the -(void)_layoutSidePanels method with this:
- (void)_layoutSidePanels {
if (self.rightPanel.isViewLoaded) {
....
}
if (self.leftPanel.isViewLoaded) {
CGRect frame = self.leftPanelContainer.bounds;
frame.size.width = floorf(self.view.bounds.size.width * self.rightGapPercentage);
if (self.shouldResizeLeftPanel) {
frame.size.width = floorf(self.view.bounds.size.width * self.rightGapPercentage);
}
self.leftPanel.view.frame = CGRectMake(0, 0, self.view.bounds.size.width * self.rightGapPercentage, self.view.bounds.size.height);
}
}
Please give me a feedback, I'm not sure if this is the problem
I think i found the solution. I replace the following code in viewDidLoad() to viewDidAppear(). The problem is after the view did appear, then it will get the correct view width.
self.centerPanelContainer = [[UIView alloc] initWithFrame:self.view.bounds];
_centerPanelRestingFrame = self.centerPanelContainer.frame;
_centerPanelHidden = NO;
self.leftPanelContainer = [[UIView alloc] initWithFrame:self.view.bounds];
NSLog(#"%f",self.leftPanelContainer.frame.size.width);
self.leftPanelContainer.hidden = YES;
self.rightPanelContainer = [[UIView alloc] initWithFrame:self.view.bounds];
self.rightPanelContainer.hidden = YES;
[self _configureContainers];
[self.view addSubview:self.centerPanelContainer];
[self.view addSubview:self.leftPanelContainer];
[self.view addSubview:self.rightPanelContainer];
self.state = JASidePanelCenterVisible;
[self _swapCenter:nil previousState:0 with:_centerPanel];
[self.view bringSubviewToFront:self.centerPanelContainer];
I have an iPad app (XCode5, ARC, Storyboards, iOS 7). This is the problem (placeholder and cursor in middle of UITextField):
This is the code that creates it:
- (IBAction)bSendFeedback:(UIButton *)sender {
// make the popover
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 450, 500)];
popoverView.backgroundColor = [UIColor colorWithWhite:(CGFloat)1.0 alpha:(CGFloat)1.0]; // frame color?
popoverContent.view = popoverView;
//resize the popover view shown in the current view to the view's size
popoverContent.contentSizeForViewInPopover = CGSizeMake(450, 500);
// add the UITextfield to the popover
UITextField *tf = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 450, 500)];
[tf becomeFirstResponder];
tf.delegate = self;
tf.tag = kSendFeedback;
tf.placeholder = #" Enter your comments here";
tf.backgroundColor = UIColorFromRGB(0xFFFFE0);
tf.returnKeyType = UIReturnKeyDone; // make return key read "Done"
[popoverView addSubview:tf];
// if previous popoverController is still visible... dismiss it
if ([popoverController isPopoverVisible]) {
[popoverController dismissPopoverAnimated:YES];
}
//create a popover controller
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[popoverController presentPopoverFromRect:((UIButton *)oSendFeedback).frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
The image is from running under iOS7; it works fine when running under iOS 6.
As you can see, it kind of works but the cursor/placeholder should be at the top of the UITextField... any ideas why it's not there when running under ios&?
It appears that Apple has changed the default vertical alignment of a UITextField to center (UIControlContentVerticalAlignmentCenter) in iOS 7 versus top (UIControlContentVerticalAlignmentTop) in iOS 6 & previous version.
To fix it in all versions, please add this line -
tf.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
This will put the cursor and placeholder text at the top. Good catch !!
Disclaimer: I'm something of an iOS n00b. I have a navigation-based app -- i.e., in my AppDelegate, I create the nav frame:
self.navigation_controller = [[UINavigationController alloc] initWithRootViewController:home_view_controller];
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
self.window.rootViewController = navigation_controller;
self.window.makeKeyAndVisible;
Inside the frame of my home view, I want a search bar, then the scrollable table view. So, I wrote this:
- viewDidLoad{
(HomeView*)home_view = [[HomeView alloc] init];
self.view = home_view
self.view.backgroundColor = [UIColor whiteColor]
(UITableView*)self.table_view = [UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.table_view.bounds.origin.y += 44;
self.table_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.table_view.dataSource = self;
self.table_view.delegate = self;
[self.view addSubview:self.table_view];
search_frame = self.view.bounds;
search_frame.origin.y = 48.0;
search_frame.size.height = 48.0;
self.search_bar = [[UISearchBar alloc] initWithFrame:search_frame)];
[self.view addSubview:self.search_bar];
}
The table view displays fine, but occupies all the space below the navigation bar. I want to have the navigation bar, then immediately below it the search bar, followed by the table view. At the point of viewDidLoad, the UITableView does not yet have a non-zero bounding rect and I expect that's part of the problem. Additionally, I've specified UIViewAutoresizingFlexibleHeight in my autoresizingMask when I really want it glued against the search bar -- again, I believe this may be part of the problem.
What have I misunderstood here?
Thanks
Steve,
Try following changes:
1) Set tableview's frame using:
CGRect targetRect = CGRectMake(0, 48, self.view.frame.size.width, self.view.frame.size.heigth);
(UITableView*)self.table_view = [UITableView alloc] initWithFrame:targetRect style:UITableViewStylePlain];
2) Add following autosize mask also:
// This value will anchor your table view with top margin
UIViewAutoresizingFlexibleBottomMargin
3) Set searchbar's frame to following rect frame:
CGRecttMake(0, 0, self.view.frame.size.width, 48);
What I would do, is just add the UISearchBar as the first UITableView header.
(method: tableView:viewForHeaderInSection:)
Check this blog post:
http://jainmarket.blogspot.com/2009/08/add-searchbar-as-uitableviews-header.html