This is a very complete iOS project, the basic implementation of some of our commonly used features, and the interface design personal feeling is quite good, is a good learning iOS project, like Friends can refer to it.
Project display, because there is no data, so all the cell display is my own writing data. SOURCE Download: Http://code.662p.com/view/11240.html Drawer Home Part effectHome effect Partial effects Found News SearchSet up Blur effect Code comment Display Code comment Display
There are a lot of details will not be shown, everyone will code run under their own view can. Because the content is more, I will follow the function module to introduce to everybody.
The first is the effect of the left drawer and the click Button Switch Controller
- Actually this is equivalent to defining a control that is similar to the system Uitabbarcontroller, at the bottom of which there is a controller (later called the Master Controller), the left button view is added to the view of the main controller, create a controller on the right side (home, Discovery, message, Set ...) And each right-hand controller is packaged with a navigation controller, the navigation controller is added sequentially to the host controller as a sub-controller, by default, the first page of the navigation controller's view is added to the host controller's view child control, Depending on the button on the left click event through the Proxy method. Remove the old controller view from the parent, add the new view to the view specific code as follows, with a temporary property before the selected controller
For the moment, do not log in the case of the click
Wnxnavigationcontroller *NEWNC = Self.childviewcontrollers[toindex];
if (Toindex = = Wnxleftbuttontypeicon) {
NEWNC = Self.childviewcontrollers[fromindex];
}
Remove the old controller view
Wnxnavigationcontroller *OLDNC = Self.childviewcontrollers[fromindex];
[Oldnc.view Removefromsuperview];
Add a new Controller view
[Self.view AddSubview:newNC.view];
NewNC.view.transform = OldNC.view.transform;
Self.showviewcontroller = Newnc.childviewcontrollers[0];
This completes the switching controller.
- The effect of the drawer is through to the Controller view to do the deformation animation, due to the function of each navigation controller, here extracted a common feature package a base class navigation controller, click the left button to complete the drawer effect
- Drag gesture is to add a uipangesturerecognizer gesture to the host controller, according to the distance to drag to calculate where to stay where, there is a lot of judgment, concrete implementation I have in the code each step has comments, reference code can
Home
- Home is a tableview can be done, tableview Headview color and data server will give back, to each Headview add a click gesture, click Push to the next controller, the color of the navigation bar will be the same as the previous Headview color ,, here because I set the theme of the navigation controller before
[Uinavigationbar appearancewhencontainedin:self, Nil]
- To not be able to directly set the color of the navigation bar here I tried setting the background color of the Navigationbar, setting the Navigationbar settintcolor:
Set the background color of the navigationbar.layer and draw the background image of the Navigationbar according to the color 4 ways can not achieve the original effect
Finally, the use of Navigationbar hidden, put a view of the pseudo-navigation bar to solve the problem
Found
- This page is a uicollectionview, there are two sets of data, each group is a headview, the need to note is the cell click event, here Notice the official practice is no matter where the cell is clicked, Will make the inside of the cell button into the highlight state, here need to use the response chain of the event, the cell's internal interception of the entire cell click events are handed to the button to do, the specific code is as follows
-(UIView *) HitTest: (cgpoint) point withevent: (Uievent *) event
{
/* Intercepts the event responder, regardless of which control in the cell is triggered to give the Iconbutton response */
1. Determine if the current control can receive events
if (self.userinteractionenabled = = NO | | self.hidden = = YES | | self.alpha <= 0.01) return nil;
2. Determine if the point is not in the current control
if ([self pointinside:point withevent:event] = = NO) return nil;
return Self.iconbutton;
}
However, it is important to note that this intercepts the cell's click event, and the CollectionView cell is clicked to trigger Diddeselectitematindexpath: It will not be triggered. My workaround is to pass the proxy method to the CollectionView when the button is clicked, externally by knowing that the cell,push is clicked on to the next controller and assigning the model of the cell to the next controller
Landing (login only and Sina Landing, not related to registration is very simple, these just go to the official website down to login and share the SDK integration can, I generally use the Friend Alliance platform, including crash statistics, three-party landing, sharing, user analysis, etc.)
News
- Same here is Tabelview, here my personal logic is to archive all the messages to the local, each click Delete one, delete the local data one, re-archive
When you click Delete all, the local archive data is emptied, and the data of the next accepted server is re-written
Because it is a simulated data, in order to ensure that every time there is data, there is no operation to implement the archive, so the re-entry after each deletion will again have data
- Here to record the state of the Edit button, read local whether there is an array of unread messages, if there is a display Edit button, record the state of the Edit button, if it is selected to hide the > picture, display the Delete button, click the Delete button to delete the local data array and refresh TableView, Here is the delete animation, you need to pay attention to the order of deletion
[Self.datas RemoveObjectAtIndex:indexPath.row];
[Self.tableview Deleterowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationright];
Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (0.3 * nsec_per_sec)), Dispatch_get_main_queue (), ^{
[Self.tableview Reloaddata];
});
- The Delete all button at the bottom is fully controlled by the edit button.
Search
Search
- This also needs to persist the storage function, each time the page pops up, first reads the user history search data from the local, the user each time deletes or the new input contraction content also writes directly to the local caches file
- Here need to mention about the hot button layout, because the popular text length is not the same, but each time there are only 4 buttons, in xib the position of the button is constrained, but the width of the constraints need two, one is >= and <= and then according to the actual length of the server returned in the Set button title, Calculate the true width of each button, figure out how much spacing is based on the true width, and reposition the button again
(void) Sethotdatas: (Nsmutablearray *) Hotdatas
{
_hotdatas = Hotdatas;
The judge is whether the length is 4, the development can write this should be the server to return a few data on how much to assign value, rather than fixed write dead data,
In case the data returned by the server is wrong, it will cause the user to flash back directly, there
When something is not very important to determine whether the return is correct, it is recommended to use
@try @catch to deal with,
Even if the returned data is incorrect, it allows the user to continue other operations,
Without causing a flashback on insignificant little detail.
if (Hotdatas.count = = 4) {
[Self.hotbutton1 settitle:hotdatas[1] forstate:uicontrolstatenormal];
[Self.hotbutton2 settitle:hotdatas[0] forstate:uicontrolstatenormal];
[Self.hotbutton3 settitle:hotdatas[2] forstate:uicontrolstatenormal];
[Self.hotbutton4 settitle:hotdatas[3] forstate:uicontrolstatenormal];
}
[Self layoutifneeded];
Figure out the spacing
CGFloat margin = (WNXAppWidth-40-
Self.hotButton1.bounds.size.width-
Self.hotButton2.bounds.size.width-
Self.hotButton3.bounds.size.width-
Self.hotButton3.bounds.size.width)/3;
Update constraint
[Self.hotbutton2 updateconstraints:^ (Masconstraintmaker *make) {
Make.left.equalTo (self.hotButton1.right). offset (margin);
}];
[Self.hotbutton3 updateconstraints:^ (Masconstraintmaker *make) {
Make.left.equalTo (self.hotButton2.right). offset (margin);
}];
[Self.hotbutton4 updateconstraints:^ (Masconstraintmaker *make) {
Make.left.equalTo (self.hotButton3.right). offset (margin);
}];
}
Blur effect Blur effect
- Here because the quality of the picture is compressed too strong, the actual effect is good, this function is iOS8 new open interface, there are two image effects can be used, one is fuzzy blur, one is color overlay (similar to the image overlay in PS effect, but on the 3 effects)
Details page Details page Show
- This page is very pit, need to pay attention to too much detail, is also my longest time of the page, it is true that there are still many bugs
- The hierarchical relationship of this page is important and needs to be focused
- The first is the navigation bar, this I see as if the navigation bar has a fade out of the animation, my practice is to put a height of 64 view at the top, based on the offset of the tableview to calculate the transparency of the view, but the transparency is only 1 or 0, The top of the ScrollView inside the ImageView, according to the number of image address returned by the server, set his display content size, and in the top of the whole scrollview add a navigation bar as the color of the view, use it to make upward push appears green effect, And the size of the stretch is calculated based on the offset of the bottom scrollview, the size of my stretch is not very accurate, and I feel the need to pin the anchor to the top.
- Then is the middle switch tableview view (later called it Select View), in order to achieve the same as Headview, card under the navigation bar effect, here because there is no navigation bar, and in the switch TableView time will not take away the selection view, So we can only put him in the same level as the top view, and also calculate his position according to the contentoffset.y of the bottom scrollview, when the offset exceeds the top of 64 o'clock, stay there, not more than the top view, The calculation here I added a lot of comments, afraid of the calculation of friends will also see understand, probably this
- Here is a ScrollView added 3 Tabelview, based on the data returned by the server to determine how many, here is the two show, and the second page has not been done
-(void) Scrollviewdidscroll: (Uiscrollview *) ScrollView
{
if (ScrollView = = Self.rmdtableview | | scrollView = = self.infotableview) {//description is tableview in scrolling
The record is currently showing the TableView.
Self.showingtableview = (UITableView *) ScrollView;
Record the distance of the last slide, because it is the scrollheadviewheight offset in the TableView contentinset, so you have to add it back.
CGFloat OffsetY = Scrollview.contentoffset.y;
CGFloat seleoffsety = offsety-self.scrolly;
self.scrolly = OffsetY;
Modifies the Scrollheadview position at the top and notifies the control within the Scrollheadview to also modify the position
CGRect headrect = self.topView.frame;
HEADRECT.ORIGIN.Y-= seleoffsety;
Self.topView.frame = Headrect;
Acreage the alpha value according to the offset, fades, and calculates the missing value when the offset is greater than-180
CGFloat startf =-180;
The initial offset Y value is the height of the top two controls
CGFloat inity = selectviewheight + scrollheadviewheight;
The missing part of the gradient Y value
CGFloat lacky = inity + startf;
Custom navigation Bar Height
CGFloat NAVIH = 64;
Fade Alpha value
CGFloat alphascalehide = 1-(OffsetY + inity-lacky)/(Inity-navih-selectviewheight-lacky);
Asymptotic Alph value
CGFloat alphascaleshow = (OffsetY + inity-lacky)/(Inity-navih-selectviewheight-lacky);
if (alphascaleshow >= 0.98) {
Show navigation Bar
[UIView animatewithduration:0.04 animations:^{
Self.naviView.alpha = 1;
}];
} else {
Self.naviView.alpha = 0;
}
Self.topScrollView.naviView.alpha = Alphascaleshow;
Self.subTitleLabel.alpha = Alphascalehide;
Self.smallImageView.alpha = Alphascalehide;
/* This piece of code is very profound. The first is to use the offset acreage directly, but when it comes back, the offsets are very high.
And then it was tragic. Changed a lot of ways. Finally enlightened t--t, this section I will be in the blog to describe in detail the various ways I use the wrong way
Using the KVO monitor offset value, switch the Selectview parent control, switch TableView headview ...
*/
if (OffsetY >=-(NAVIH + selectviewheight)) {
Self.selectView.frame = CGRectMake (0, NAVIH, Wnxappwidth, selectviewheight);
} else {
Self.selectView.frame = CGRectMake (0, Cgrectgetmaxy (self.topView.frame), Wnxappwidth, selectviewheight);
}
CGFloat Scaletopview = 1-(OffsetY + selectviewheight + scrollheadviewheight)/100;
Scaletopview = scaletopview > 1? Scaletopview:1;
Figure out the deformation of the head here the animation is not very accurate, good animation is 1.1 points to try out here may also need to cooperate with the anchor point to animate, about this animation I will open a project in the future with the blog to explain here This is not fine tune
Cgaffinetransform transform = Cgaffinetransformmakescale (Scaletopview, Scaletopview);
CGFloat ty = (scaleTopView-1) * scrollheadviewheight;
Self.topView.transform = cgaffinetransformtranslate (transform, 0,-ty * 0.2);
Record the offset of the selectviewy axis, this is used to calculate each switch tableview, so that the new TableView is always used in the head,
Now the brain is a little confused to calculate it. 2.57 minutes in the morning ~
CGFloat selectviewoffsety = self.selectview.frame.origin.y-scrollheadviewheight;
if (selectviewoffsety! =-scrollheadviewheight && selectviewoffsety = (0.5 + index)) {
[Self.selectview Linetoindex:index + 1];
} else if (Seleoffsetx < 0 && Offsetx/wnxappwidth <= (0.5 + index)) {
[Self.selectview Linetoindex:index];
}
}
}
These are the general idea of this project, of course, there are a lot of details in the code, the first attempt to write ideas, feel a lot of shortcomings, this should be a summary of every function, and I was released in the evening back to summarize, there are a lot of ideas at the time is not very clear ...
Please open wnxhuntforcity.xcworkspace directly Open it
And don't open wnxhuntforcity.xcodeproj.
|